@@ -1806,113 +1806,79 @@ object desugar {
1806
1806
* corresponding to whether this is a for-do or a for-yield.
1807
1807
* If betterFors are enabled, the creation performs the following rewrite rules:
1808
1808
*
1809
- * 1.
1809
+ * 1. if betterFors is enabled:
1810
1810
*
1811
- * for (P <- G) do E ==> G.foreach (P => E)
1811
+ * for () do E ==> E
1812
+ * or
1813
+ * for () yield E ==> E
1812
1814
*
1813
- * Here and in the following (P => E) is interpreted as the function (P => E)
1814
- * if P is a variable pattern and as the partial function { case P => E } otherwise.
1815
+ * (Where empty for-comprehensions are excluded by the parser)
1815
1816
*
1816
1817
* 2.
1817
1818
*
1818
- * for (P <- G) yield P ==> G
1819
- *
1820
- * If P is a variable or a tuple of variables and G is not a withFilter.
1819
+ * for (P <- G) do E ==> G.foreach (P => E)
1821
1820
*
1822
- * for (P <- G) yield E ==> G.map (P => E)
1823
- *
1824
- * Otherwise
1821
+ * Here and in the following (P => E) is interpreted as the function (P => E)
1822
+ * if P is a variable pattern and as the partial function { case P => E } otherwise.
1825
1823
*
1826
1824
* 3.
1827
1825
*
1828
- * for (P_1 <- G_1; P_2 <- G_2; ...) ...
1829
- * ==>
1830
- * G_1.flatMap (P_1 => for (P_2 <- G_2; ...) ...)
1831
- *
1832
- * 4.
1833
- *
1834
- * for (P <- G; if E; ...) ...
1835
- * ==>
1836
- * for (P <- G.withFilter (P => E); ...) ...
1837
- *
1838
- * 5. For any N:
1839
- *
1840
- * for (P <- G; P_1 = E_1; ... P_N = E_N; rest)
1841
- * ==>
1842
- * G.flatMap (P => for (P_1 = E_1; ... P_N = E_N; ...)) if rest contains (<-)
1843
- * G.map (P => for (P_1 = E_1; ... P_N = E_N; ...)) otherwise
1826
+ * for (P <- G) yield P ==> G
1844
1827
*
1845
- * 6. For any N:
1828
+ * If betterFors is enabled, P is a variable or a tuple of variables and G is not a withFilter.
1846
1829
*
1847
- * for (P <- G; P_1 = E_1; ... P_N = E_N; if E; ...)
1848
- * ==>
1849
- * for (TupleN(P, P_1, ... P_N) <-
1850
- * for (x @ P <- G) yield {
1851
- * val x_1 @ P_1 = E_2
1852
- * ...
1853
- * val x_N @ P_N = E_N
1854
- * TupleN(x, x_1, ..., x_N)
1855
- * }; if E; ...)
1856
- *
1857
- * If any of the P_i are variable patterns, the corresponding `x_i @ P_i` is not generated
1858
- * and the variable constituting P_i is used instead of x_i
1859
- *
1860
- * 7. For any N:
1861
- *
1862
- * for (P_1 = E_1; ... P_N = E_N; ...)
1863
- * ==>
1864
- * {
1865
- * val x_N @ P_N = E_N
1866
- * for (...)
1867
- * }
1868
- *
1869
- * 8.
1870
- * for () yield E ==> E
1871
- *
1872
- * (Where empty for-comprehensions are excluded by the parser)
1830
+ * for (P <- G) yield E ==> G.map (P => E)
1873
1831
*
1874
- * If the aliases are not followed by a guard, otherwise an error.
1875
- *
1876
- * With betterFors disabled, the translation is as follows:
1877
- *
1878
- * 1.
1832
+ * Otherwise
1879
1833
*
1880
- * for (P <- G) E ==> G.foreach (P => E)
1834
+ * 4.
1881
1835
*
1882
- * Here and in the following (P => E) is interpreted as the function (P => E)
1883
- * if P is a variable pattern and as the partial function { case P => E } otherwise.
1836
+ * for (P_1 <- G_1; P_2 <- G_2; ...) ...
1837
+ * ==>
1838
+ * G_1.flatMap (P_1 => for (P_2 <- G_2; ...) ...)
1884
1839
*
1885
- * 2 .
1840
+ * 5 .
1886
1841
*
1887
- * for (P <- G) yield E ==> G.map (P => E)
1842
+ * for (P <- G; if E; ...) ...
1843
+ * ==>
1844
+ * for (P <- G.withFilter (P => E); ...) ...
1888
1845
*
1889
- * 3.
1846
+ * 6. For any N, if betterFors is enabled:
1890
1847
*
1891
- * for (P_1 <- G_1; P_2 <- G_2 ; ...) ...
1848
+ * for (P <- G; P_1 = E_1; ... P_N = E_N; P1 <- G1 ; ...) ...
1892
1849
* ==>
1893
- * G_1 .flatMap (P_1 => for (P_2 <- G_2 ; ...) ...)
1850
+ * G .flatMap (P => for (P_1 = E_1 ; ... P_N = E_N; ...) )
1894
1851
*
1895
- * 4.
1852
+ * 7. For any N, if betterFors is enabled:
1896
1853
*
1897
- * for (P <- G; E ; ...) ...
1898
- * =>
1899
- * for (P <- G.filter (P => E) ; ...) ...
1854
+ * for (P <- G; P_1 = E_1 ; ... P_N = E_N ) ...
1855
+ * == >
1856
+ * G.map (P => for (P_1 = E_1 ; ... P_N = E_N ) ...)
1900
1857
*
1901
- * 5 . For any N:
1858
+ * 8 . For any N:
1902
1859
*
1903
- * for (P_1 <- G; P_2 = E_2; val P_N = E_N; ...)
1860
+ * for (P <- G; P_1 = E_1; ... P_N = E_N; ...)
1904
1861
* ==>
1905
- * for (TupleN(P_1, P_2 , ... P_N) <-
1906
- * for (x_1 @ P_1 <- G) yield {
1907
- * val x_2 @ P_2 = E_2
1862
+ * for (TupleN(P, P_1 , ... P_N) <-
1863
+ * for (x @ P <- G) yield {
1864
+ * val x_1 @ P_1 = E_2
1908
1865
* ...
1909
- * val x_N & P_N = E_N
1910
- * TupleN(x_1, ..., x_N)
1911
- * } ...)
1866
+ * val x_N @ P_N = E_N
1867
+ * TupleN(x, x_1, ..., x_N)
1868
+ * }; if E; ...)
1912
1869
*
1913
1870
* If any of the P_i are variable patterns, the corresponding `x_i @ P_i` is not generated
1914
1871
* and the variable constituting P_i is used instead of x_i
1915
1872
*
1873
+ * 9. For any N, if betterFors is enabled:
1874
+ *
1875
+ * for (P_1 = E_1; ... P_N = E_N; ...)
1876
+ * ==>
1877
+ * {
1878
+ * val x_N @ P_N = E_N
1879
+ * for (...)
1880
+ * }
1881
+ *
1916
1882
* @param mapName The name to be used for maps (either map or foreach)
1917
1883
* @param flatMapName The name to be used for flatMaps (either flatMap or foreach)
1918
1884
* @param enums The enumerators in the for expression
@@ -2037,86 +2003,59 @@ object desugar {
2037
2003
case (Tuple (ts1), Tuple (ts2)) => ts1.corresponds(ts2)(deepEquals)
2038
2004
case _ => false
2039
2005
2040
- if betterForsEnabled then
2041
- enums match {
2042
- case Nil => body
2043
- case (gen : GenFrom ) :: Nil =>
2044
- if gen.checkMode != GenCheckMode .Filtered // results of withFilter have the wrong type
2045
- && deepEquals(gen.pat, body)
2046
- then gen.expr // avoid a redundant map with identity
2047
- else Apply (rhsSelect(gen, mapName), makeLambda(gen, body))
2048
- case (gen : GenFrom ) :: rest
2049
- if rest.dropWhile(_.isInstanceOf [GenAlias ]).headOption.forall(e => e.isInstanceOf [GenFrom ]) =>
2050
- val cont = makeFor(mapName, flatMapName, rest, body)
2051
- val selectName =
2052
- if rest.exists(_.isInstanceOf [GenFrom ]) then flatMapName
2053
- else mapName
2054
- Apply (rhsSelect(gen, selectName), makeLambda(gen, cont))
2055
- case (gen : GenFrom ) :: (rest @ GenAlias (_, _) :: _) =>
2056
- val (valeqs, rest1) = rest.span(_.isInstanceOf [GenAlias ])
2057
- val pats = valeqs map { case GenAlias (pat, _) => pat }
2058
- val rhss = valeqs map { case GenAlias (_, rhs) => rhs }
2059
- val (defpat0, id0) = makeIdPat(gen.pat)
2060
- val (defpats, ids) = (pats map makeIdPat).unzip
2061
- val pdefs = valeqs.lazyZip(defpats).lazyZip(rhss).map { (valeq, defpat, rhs) =>
2062
- val mods = defpat match
2063
- case defTree : DefTree => defTree.mods
2064
- case _ => Modifiers ()
2065
- makePatDef(valeq, mods, defpat, rhs)
2066
- }
2067
- val rhs1 = makeFor(nme.map, nme.flatMap, GenFrom (defpat0, gen.expr, gen.checkMode) :: Nil , Block (pdefs, makeTuple(id0 :: ids)))
2068
- val allpats = gen.pat :: pats
2069
- val vfrom1 = GenFrom (makeTuple(allpats), rhs1, GenCheckMode .Ignore )
2070
- makeFor(mapName, flatMapName, vfrom1 :: rest1, body)
2071
- case (gen : GenFrom ) :: test :: rest =>
2072
- val filtered = Apply (rhsSelect(gen, nme.withFilter), makeLambda(gen, test))
2073
- val genFrom = GenFrom (gen.pat, filtered, GenCheckMode .Filtered )
2074
- makeFor(mapName, flatMapName, genFrom :: rest, body)
2075
- case GenAlias (_, _) :: _ =>
2076
- val (valeqs, rest) = enums.span(_.isInstanceOf [GenAlias ])
2077
- val pats = valeqs.map { case GenAlias (pat, _) => pat }
2078
- val rhss = valeqs.map { case GenAlias (_, rhs) => rhs }
2079
- val (defpats, ids) = pats.map(makeIdPat).unzip
2080
- val pdefs = valeqs.lazyZip(defpats).lazyZip(rhss).map { (valeq, defpat, rhs) =>
2081
- val mods = defpat match
2082
- case defTree : DefTree => defTree.mods
2083
- case _ => Modifiers ()
2084
- makePatDef(valeq, mods, defpat, rhs)
2085
- }
2086
- Block (pdefs, makeFor(mapName, flatMapName, rest, body))
2087
- case _ =>
2088
- EmptyTree // may happen for erroneous input
2089
- }
2090
- else {
2091
- enums match {
2092
- case (gen : GenFrom ) :: Nil =>
2093
- Apply (rhsSelect(gen, mapName), makeLambda(gen, body))
2094
- case (gen : GenFrom ) :: (rest @ (GenFrom (_, _, _) :: _)) =>
2095
- val cont = makeFor(mapName, flatMapName, rest, body)
2096
- Apply (rhsSelect(gen, flatMapName), makeLambda(gen, cont))
2097
- case (gen : GenFrom ) :: (rest @ GenAlias (_, _) :: _) =>
2098
- val (valeqs, rest1) = rest.span(_.isInstanceOf [GenAlias ])
2099
- val pats = valeqs map { case GenAlias (pat, _) => pat }
2100
- val rhss = valeqs map { case GenAlias (_, rhs) => rhs }
2101
- val (defpat0, id0) = makeIdPat(gen.pat)
2102
- val (defpats, ids) = (pats map makeIdPat).unzip
2103
- val pdefs = valeqs.lazyZip(defpats).lazyZip(rhss).map { (valeq, defpat, rhs) =>
2104
- val mods = defpat match
2105
- case defTree : DefTree => defTree.mods
2106
- case _ => Modifiers ()
2107
- makePatDef(valeq, mods, defpat, rhs)
2108
- }
2109
- val rhs1 = makeFor(nme.map, nme.flatMap, GenFrom (defpat0, gen.expr, gen.checkMode) :: Nil , Block (pdefs, makeTuple(id0 :: ids)))
2110
- val allpats = gen.pat :: pats
2111
- val vfrom1 = GenFrom (makeTuple(allpats), rhs1, GenCheckMode .Ignore )
2112
- makeFor(mapName, flatMapName, vfrom1 :: rest1, body)
2113
- case (gen : GenFrom ) :: test :: rest =>
2114
- val filtered = Apply (rhsSelect(gen, nme.withFilter), makeLambda(gen, test))
2115
- val genFrom = GenFrom (gen.pat, filtered, GenCheckMode .Ignore )
2116
- makeFor(mapName, flatMapName, genFrom :: rest, body)
2117
- case _ =>
2118
- EmptyTree // may happen for erroneous input
2119
- }
2006
+ enums match {
2007
+ case Nil if betterForsEnabled => body
2008
+ case (gen : GenFrom ) :: Nil =>
2009
+ if betterForsEnabled
2010
+ && gen.checkMode != GenCheckMode .Filtered // results of withFilter have the wrong type
2011
+ && deepEquals(gen.pat, body)
2012
+ then gen.expr // avoid a redundant map with identity
2013
+ else Apply (rhsSelect(gen, mapName), makeLambda(gen, body))
2014
+ case (gen : GenFrom ) :: (rest @ (GenFrom (_, _, _) :: _)) =>
2015
+ val cont = makeFor(mapName, flatMapName, rest, body)
2016
+ Apply (rhsSelect(gen, flatMapName), makeLambda(gen, cont))
2017
+ case (gen : GenFrom ) :: rest
2018
+ if betterForsEnabled
2019
+ && rest.dropWhile(_.isInstanceOf [GenAlias ]).headOption.forall(e => e.isInstanceOf [GenFrom ]) => // possible aliases followed by a generator or end of for
2020
+ val cont = makeFor(mapName, flatMapName, rest, body)
2021
+ val selectName =
2022
+ if rest.exists(_.isInstanceOf [GenFrom ]) then flatMapName
2023
+ else mapName
2024
+ Apply (rhsSelect(gen, selectName), makeLambda(gen, cont))
2025
+ case (gen : GenFrom ) :: (rest @ GenAlias (_, _) :: _) =>
2026
+ val (valeqs, rest1) = rest.span(_.isInstanceOf [GenAlias ])
2027
+ val pats = valeqs map { case GenAlias (pat, _) => pat }
2028
+ val rhss = valeqs map { case GenAlias (_, rhs) => rhs }
2029
+ val (defpat0, id0) = makeIdPat(gen.pat)
2030
+ val (defpats, ids) = (pats map makeIdPat).unzip
2031
+ val pdefs = valeqs.lazyZip(defpats).lazyZip(rhss).map { (valeq, defpat, rhs) =>
2032
+ val mods = defpat match
2033
+ case defTree : DefTree => defTree.mods
2034
+ case _ => Modifiers ()
2035
+ makePatDef(valeq, mods, defpat, rhs)
2036
+ }
2037
+ val rhs1 = makeFor(nme.map, nme.flatMap, GenFrom (defpat0, gen.expr, gen.checkMode) :: Nil , Block (pdefs, makeTuple(id0 :: ids)))
2038
+ val allpats = gen.pat :: pats
2039
+ val vfrom1 = GenFrom (makeTuple(allpats), rhs1, GenCheckMode .Ignore )
2040
+ makeFor(mapName, flatMapName, vfrom1 :: rest1, body)
2041
+ case (gen : GenFrom ) :: test :: rest =>
2042
+ val filtered = Apply (rhsSelect(gen, nme.withFilter), makeLambda(gen, test))
2043
+ val genFrom = GenFrom (gen.pat, filtered, if betterForsEnabled then GenCheckMode .Filtered else GenCheckMode .Ignore )
2044
+ makeFor(mapName, flatMapName, genFrom :: rest, body)
2045
+ case GenAlias (_, _) :: _ if betterForsEnabled =>
2046
+ val (valeqs, rest) = enums.span(_.isInstanceOf [GenAlias ])
2047
+ val pats = valeqs.map { case GenAlias (pat, _) => pat }
2048
+ val rhss = valeqs.map { case GenAlias (_, rhs) => rhs }
2049
+ val (defpats, ids) = pats.map(makeIdPat).unzip
2050
+ val pdefs = valeqs.lazyZip(defpats).lazyZip(rhss).map { (valeq, defpat, rhs) =>
2051
+ val mods = defpat match
2052
+ case defTree : DefTree => defTree.mods
2053
+ case _ => Modifiers ()
2054
+ makePatDef(valeq, mods, defpat, rhs)
2055
+ }
2056
+ Block (pdefs, makeFor(mapName, flatMapName, rest, body))
2057
+ case _ =>
2058
+ EmptyTree // may happen for erroneous input
2120
2059
}
2121
2060
}
2122
2061
0 commit comments