Skip to content

Commit f0e54c5

Browse files
committed
Allow pattern matching anonymous functions of arity > 1
This is sepcified in Sec. 8.5 of the SLS. Fixes #873. Review by @smarter.
1 parent 201ce2f commit f0e54c5

File tree

3 files changed

+20
-6
lines changed

3 files changed

+20
-6
lines changed

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -556,14 +556,20 @@ object desugar {
556556
DefDef(nme.ANON_FUN, Nil, params :: Nil, tpt, body).withMods(synthetic),
557557
Closure(Nil, Ident(nme.ANON_FUN), EmptyTree))
558558

559-
/** Expand partial function
559+
/** If `nparams` == 1, expand partial function
560+
*
560561
* { cases }
561562
* ==>
562-
* x$0 => x$0 match { cases }
563+
* x$1 => x$1 match { cases }
564+
*
565+
* If `nparams` != 1, expand instead to
566+
*
567+
* (x$0, ..., x${n-1}) => (x$0, ..., x${n-1}) match { cases }
563568
*/
564-
def makeCaseLambda(cases: List[CaseDef])(implicit ctx: Context) = {
565-
val param = makeSyntheticParameter()
566-
Function(param :: Nil, Match(Ident(param.name), cases))
569+
def makeCaseLambda(cases: List[CaseDef], nparams: Int = 1)(implicit ctx: Context) = {
570+
val params = (1 to nparams).toList.map(makeSyntheticParameter(_))
571+
val selector = makeTuple(params.map(p => Ident(p.name)))
572+
Function(params, Match(selector, cases))
567573
}
568574

569575
/** Add annotation with class `cls` to tree:

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,11 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
629629
def typedMatch(tree: untpd.Match, pt: Type)(implicit ctx: Context) = track("typedMatch") {
630630
tree.selector match {
631631
case EmptyTree =>
632-
typed(desugar.makeCaseLambda(tree.cases) withPos tree.pos, pt)
632+
val arity = pt match {
633+
case defn.FunctionType(args, _) => args.length
634+
case _ => 1
635+
}
636+
typed(desugar.makeCaseLambda(tree.cases, arity) withPos tree.pos, pt)
633637
case _ =>
634638
val sel1 = typedExpr(tree.selector)
635639
val selType = widenForMatchSelector(

tests/pos/i873.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
object Test {
2+
def call(k: (Int, Int) => Unit): Unit = ???
3+
def test = call({ case (x, y) => ()})
4+
}

0 commit comments

Comments
 (0)