@@ -1807,38 +1807,44 @@ object desugar {
1807
1807
*
1808
1808
* 1.
1809
1809
*
1810
- * for (P <- G) E ==> G.foreach (P => E)
1810
+ * for (P <- G) E ==> G.foreach (P => E)
1811
1811
*
1812
- * Here and in the following (P => E) is interpreted as the function (P => E)
1813
- * if P is a variable pattern and as the partial function { case P => E } otherwise.
1812
+ * Here and in the following (P => E) is interpreted as the function (P => E)
1813
+ * if P is a variable pattern and as the partial function { case P => E } otherwise.
1814
1814
*
1815
1815
* 2.
1816
1816
*
1817
- * for (P <- G) yield E ==> G.map (P => E)
1817
+ * for (P <- G) yield P ==> G
1818
+ *
1819
+ * if P is a variable or a tuple of variables and G is not a withFilter.
1820
+ *
1821
+ * for (P <- G) yield E ==> G.map (P => E)
1822
+ *
1823
+ * otherwise
1818
1824
*
1819
1825
* 3.
1820
1826
*
1821
- * for (P_1 <- G_1; P_2 <- G_2; ...) ...
1822
- * ==>
1823
- * G_1.flatMap (P_1 => for (P_2 <- G_2; ...) ...)
1827
+ * for (P_1 <- G_1; P_2 <- G_2; ...) ...
1828
+ * ==>
1829
+ * G_1.flatMap (P_1 => for (P_2 <- G_2; ...) ...)
1824
1830
*
1825
1831
* 4.
1826
1832
*
1827
- * for (P <- G; E; ...) ...
1828
- * =>
1829
- * for (P <- G.filter (P => E); ...) ...
1833
+ * for (P <- G; E; ...) ...
1834
+ * =>
1835
+ * for (P <- G.filter (P => E); ...) ...
1830
1836
*
1831
1837
* 5. For any N:
1832
1838
*
1833
- * for (P_1 <- G; P_2 = E_2; val P_N = E_N; ...)
1834
- * ==>
1835
- * for (TupleN(P_1, P_2, ... P_N) <-
1836
- * for (x_1 @ P_1 <- G) yield {
1837
- * val x_2 @ P_2 = E_2
1838
- * ...
1839
- * val x_N & P_N = E_N
1840
- * TupleN(x_1, ..., x_N)
1841
- * } ...)
1839
+ * for (P_1 <- G; P_2 = E_2; val P_N = E_N; ...)
1840
+ * ==>
1841
+ * for (TupleN(P_1, P_2, ... P_N) <-
1842
+ * for (x_1 @ P_1 <- G) yield {
1843
+ * val x_2 @ P_2 = E_2
1844
+ * ...
1845
+ * val x_N & P_N = E_N
1846
+ * TupleN(x_1, ..., x_N)
1847
+ * } ...)
1842
1848
*
1843
1849
* If any of the P_i are variable patterns, the corresponding `x_i @ P_i` is not generated
1844
1850
* and the variable constituting P_i is used instead of x_i
@@ -1951,7 +1957,7 @@ object desugar {
1951
1957
case GenCheckMode .FilterAlways => false // pattern was prefixed by `case`
1952
1958
case GenCheckMode .FilterNow | GenCheckMode .CheckAndFilter => isVarBinding(gen.pat) || isIrrefutable(gen.pat, gen.expr)
1953
1959
case GenCheckMode .Check => true
1954
- case GenCheckMode .Ignore => true
1960
+ case GenCheckMode .Ignore | GenCheckMode . Filtered => true
1955
1961
1956
1962
/** rhs.name with a pattern filter on rhs unless `pat` is irrefutable when
1957
1963
* matched against `rhs`.
@@ -1961,9 +1967,18 @@ object desugar {
1961
1967
Select (rhs, name)
1962
1968
}
1963
1969
1970
+ def deepEquals (t1 : Tree , t2 : Tree ): Boolean =
1971
+ (unsplice(t1), unsplice(t2)) match
1972
+ case (Ident (n1), Ident (n2)) => n1 == n2
1973
+ case (Tuple (ts1), Tuple (ts2)) => ts1.corresponds(ts2)(deepEquals)
1974
+ case _ => false
1975
+
1964
1976
enums match {
1965
1977
case (gen : GenFrom ) :: Nil =>
1966
- Apply (rhsSelect(gen, mapName), makeLambda(gen, body))
1978
+ if gen.checkMode != GenCheckMode .Filtered // results of withFilter have the wrong type
1979
+ && deepEquals(gen.pat, body)
1980
+ then gen.expr // avoid a redundant map with identity
1981
+ else Apply (rhsSelect(gen, mapName), makeLambda(gen, body))
1967
1982
case (gen : GenFrom ) :: (rest @ (GenFrom (_, _, _) :: _)) =>
1968
1983
val cont = makeFor(mapName, flatMapName, rest, body)
1969
1984
Apply (rhsSelect(gen, flatMapName), makeLambda(gen, cont))
@@ -1985,7 +2000,7 @@ object desugar {
1985
2000
makeFor(mapName, flatMapName, vfrom1 :: rest1, body)
1986
2001
case (gen : GenFrom ) :: test :: rest =>
1987
2002
val filtered = Apply (rhsSelect(gen, nme.withFilter), makeLambda(gen, test))
1988
- val genFrom = GenFrom (gen.pat, filtered, GenCheckMode .Ignore )
2003
+ val genFrom = GenFrom (gen.pat, filtered, GenCheckMode .Filtered )
1989
2004
makeFor(mapName, flatMapName, genFrom :: rest, body)
1990
2005
case _ =>
1991
2006
EmptyTree // may happen for erroneous input
0 commit comments