Skip to content

Commit 675a43b

Browse files
authored
Fix irrefutability checking in for with untupling (#23273)
Before this PR, the two for comprehensions in the added test case behaved differently: ```scala -- 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`).
1 parent 606268f commit 675a43b

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1938,9 +1938,11 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
19381938
// to
19391939
// (a1, ..., aN) => e
19401940
val params1 = desugar.patternsToParams(elems)
1941+
val matchCheck = scrut.getAttachment(desugar.CheckIrrefutable)
1942+
.getOrElse(desugar.MatchCheck.IrrefutablePatDef)
19411943
desugared = if params1.hasSameLengthAs(elems)
19421944
then cpy.Function(tree)(params1, rhs)
1943-
else desugar.makeCaseLambda(cases, desugar.MatchCheck.IrrefutablePatDef, protoFormals.length)
1945+
else desugar.makeCaseLambda(cases, matchCheck, protoFormals.length)
19441946
case _ =>
19451947

19461948
if desugared.isEmpty then

tests/neg/irrefutable-genfrom.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
object Test:
2+
def one: Unit =
3+
for
4+
// Was already an error as expected
5+
(i, Some(_)) <- List.empty[Int] zip List.empty[Option[String]] // error
6+
do ()
7+
8+
def two: Unit =
9+
for
10+
// Used to be a warning
11+
(i, Some(_)) <- List.empty[Int] lazyZip List.empty[Option[String]] // error
12+
do ()

0 commit comments

Comments
 (0)