scala3 icon indicating copy to clipboard operation
scala3 copied to clipboard

Fix irrefutability checking in `for` with untupling

Open smarter opened this issue 6 months ago • 0 comments

Before this PR, the two for comprehensions in the added test case behaved differently:

-- Error: tests/neg/irrefutable-genfrom.scala:5:10 -----------------------------
5 |      (i, Some(_)) <- List.empty[Int] zip List.empty[Option[String]] // error
  |          ^^^^^^^
  |pattern's type Some[String] is more specialized than the right hand side expression's type Option[String]
  |
  |If the narrowing is intentional, this can be communicated by adding the `case` keyword before the full pattern,
  |which will result in a filtering for expression (using `withFilter`).
  |This patch can be rewritten automatically under -rewrite -source 3.2-migration.
-- Warning: tests/neg/irrefutable-genfrom.scala:11:6 ---------------------------
11 |      (i, Some(_)) <- List.empty[Int] lazyZip List.empty[Option[String]] // error
   |      ^
   |pattern's type Some[String] is more specialized than the right hand side expression's type Option[String]
   |
   |If the narrowing is intentional, this can be communicated by adding `: @unchecked` after the expression,
   |which may result in a MatchError at runtime.
   |This patch can be rewritten automatically under -rewrite -source 3.2-migration.

The second one was incorrect: just like the first one, we should use the case keyword to make the pattern partial since we're in a for comprehension, but this information was lost when calling makeCaseLambda in typedFunctionValue. To fix this, we need to retrieve the attachment in the scrutinee (it was added there by makeSelector called from makeCaseLambda called from makeLambda called from makeFor in Desugar.scala).

smarter avatar May 27 '25 16:05 smarter