Skip to content

Commit 6221361

Browse files
Fix untupling of functions in for comprehensions
1 parent 5c628d9 commit 6221361

File tree

3 files changed

+22
-6
lines changed

3 files changed

+22
-6
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,10 +1547,22 @@ object desugar {
15471547
*
15481548
* If `nparams` != 1, expand instead to
15491549
*
1550-
* (x$1, ..., x$n) => (x$0, ..., x${n-1} @unchecked?) match { cases }
1550+
* (x$1, ..., x$n) => (x$1, ..., x$n @unchecked?) match { cases }
1551+
*
1552+
* Unless there is a single irrefutable case, then can reuse the rhs
1553+
*
1554+
* { case (a1, ..., an) => rhs }
1555+
* ==>
1556+
* (a1, ..., an) => rhs
15511557
*/
15521558
def makeCaseLambda(cases: List[CaseDef], checkMode: MatchCheck, nparams: Int = 1)(using Context): Function = {
1553-
val params = (1 to nparams).toList.map(makeSyntheticParameter(_))
1559+
val params = cases match
1560+
case List(CaseDef(untpd.Tuple(elems), untpd.EmptyTree, rhs)) if elems.sizeIs == nparams =>
1561+
patternsToParams(elems) match
1562+
case params if params.sizeIs == nparams => params
1563+
case _ => (1 to nparams).toList.map(makeSyntheticParameter(_))
1564+
case _ => (1 to nparams).toList.map(makeSyntheticParameter(_))
1565+
15541566
val selector = makeTuple(params.map(p => Ident(p.name)))
15551567
Function(params, Match(makeSelector(selector, checkMode), cases))
15561568
}

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,15 +1621,14 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
16211621
case untpd.Annotated(scrut1, _) => isParamRef(scrut1)
16221622
case untpd.Ident(id) => id == params.head.name
16231623
fnBody match
1624-
case untpd.Match(scrut, untpd.CaseDef(untpd.Tuple(elems), untpd.EmptyTree, rhs) :: Nil)
1624+
case untpd.Match(scrut, cases @ untpd.CaseDef(untpd.Tuple(elems), untpd.EmptyTree, rhs) :: Nil)
16251625
if scrut.span.isSynthetic && isParamRef(scrut) && elems.hasSameLengthAs(protoFormals) =>
16261626
// If `pt` is N-ary function type, convert synthetic lambda
16271627
// x$1 => x$1 match case (a1, ..., aN) => e
16281628
// to
16291629
// (a1, ..., aN) => e
1630-
val params1 = desugar.patternsToParams(elems)
1631-
if params1.hasSameLengthAs(elems) then
1632-
desugared = cpy.Function(tree)(params1, rhs)
1630+
desugared = desugar.makeCaseLambda(
1631+
cases, desugar.MatchCheck.IrrefutablePatDef, protoFormals.length)
16331632
case _ =>
16341633

16351634
if desugared.isEmpty then

tests/pos/i19576.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
object Test:
3+
val a = Seq(0 -> 1, 2 -> 3)
4+
val c = Seq("A", "B")
5+
val z = for ((beg, end), c) <- a.lazyZip(c) yield c // Error before changes

0 commit comments

Comments
 (0)