From 7ee2683ebc70e904ef9daa6d1d23229e8f71f5d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 4 Oct 2024 17:27:07 +0200 Subject: [PATCH] Fix #20271: Bring for comprehension spec up to date. Since Scala 3.4, a `withFilter` is generated if and only if the generator has the `case` modifier. If it does not, the pattern must be irrefutable. [Cherry-picked 127bb7bf5c24dbcac780d3f5c5bc7ef1ca1821e5] --- docs/_spec/06-expressions.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/_spec/06-expressions.md b/docs/_spec/06-expressions.md index 5043e752ebe6..a633c30e0e4b 100644 --- a/docs/_spec/06-expressions.md +++ b/docs/_spec/06-expressions.md @@ -729,8 +729,9 @@ A _for loop_ `for (´\mathit{enums}\,´) ´e´` executes expression ´e´ for ea A _for comprehension_ `for (´\mathit{enums}\,´) yield ´e´` evaluates expression ´e´ for each binding generated by the enumerators ´\mathit{enums}´ and collects the results. An enumerator sequence always starts with a generator; this can be followed by further generators, value definitions, or guards. -A _generator_ `´p´ <- ´e´` produces bindings from an expression ´e´ which is matched in some way against pattern ´p´. -Optionally, `case` can appear in front of a generator pattern, this has no meaning in Scala 2 but will be [required in Scala 3 if `p` is not irrefutable](https://docs.scala-lang.org/scala3/reference/changed-features/pattern-bindings.html). +A _generator_ `´p´ <- ´e´` produces bindings from an expression ´e´ which is deconstructed by the pattern ´p´. +The pattern must be [irrefutable](08-pattern-matching.html#irrefutable-patterns). +A _conditional generator_ `case ´p´ <- ´e´` tests whether elements produced by ´e´ match the pattern and discards the ones that do not match. A _value definition_ `´p´ = ´e´` binds the value name ´p´ (or several names in a pattern ´p´) to the result of evaluating the expression ´e´. A _guard_ `if ´e´` contains a boolean expression which restricts enumerated bindings. @@ -738,7 +739,7 @@ The precise meaning of generators and guards is defined by translation to invoca These methods can be implemented in different ways for different carrier types. The translation scheme is as follows. -In a first step, every generator `´p´ <- ´e´`, where ´p´ is not [irrefutable](08-pattern-matching.html#patterns) for the type of ´e´ is replaced by +In a first step, every generator `case ´p´ <- ´e´` is replaced by ```scala ´p´ <- ´e´.withFilter { case ´p´ => true; case _ => false } @@ -772,7 +773,7 @@ Then, the following rules are applied repeatedly until all comprehensions have b ´e´.foreach { case ´p´ => for (´p'´ <- ´e'; ...´) ´e''´ } ``` - - A generator `´p´ <- ´e´` followed by a guard `if ´g´` is translated to a single generator `´p´ <- ´e´.withFilter((´x_1, ..., x_n´) => ´g\,´)` where ´x_1, ..., x_n´ are the free variables of ´p´. + - A generator `´p´ <- ´e´` followed by a guard `if ´g´` is translated to a single generator `´p´ <- ´e´.withFilter({ case ´p´ => ´g\,´ })`. - A generator `´p´ <- ´e´` followed by a value definition `´p'´ = ´e'´` is translated to the following generator of pairs of values, where ´x´ and ´x'´ are fresh names: