From 17296763448bf86c9f95b1458e5722b9829e8b3e Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 16 Feb 2016 16:11:09 +0100 Subject: [PATCH] Untuple using `def` not `val`. As retronym noted on #897, `val` forces to early. --- src/dotty/tools/dotc/ast/Desugar.scala | 9 +++++---- src/dotty/tools/dotc/typer/Typer.scala | 2 +- tests/run/function-arity.scala | 8 ++++++++ 3 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 tests/run/function-arity.scala diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala index c1083d26d283..991940f10944 100644 --- a/src/dotty/tools/dotc/ast/Desugar.scala +++ b/src/dotty/tools/dotc/ast/Desugar.scala @@ -591,18 +591,19 @@ object desugar { /** Map n-ary function `(p1, ..., pn) => body` where n != 1 to unary function as follows: * * x$1 => { - * val p1 = x$1._1 + * def p1 = x$1._1 * ... - * val pn = x$1._n + * def pn = x$1._n * body * } */ - def makeUnaryCaseLambda(params: List[ValDef], body: Tree)(implicit ctx: Context): Tree = { + def makeTupledFunction(params: List[ValDef], body: Tree)(implicit ctx: Context): Tree = { val param = makeSyntheticParameter() def selector(n: Int) = Select(refOfDef(param), nme.selectorName(n)) val vdefs = params.zipWithIndex.map{ - case(param, idx) => cpy.ValDef(param)(rhs = selector(idx)) + case (param, idx) => + DefDef(param.name, Nil, Nil, TypeTree(), selector(idx)).withPos(param.pos) } Function(param :: Nil, Block(vdefs, body)) } diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index f1e1d9286b11..4d2ab3552d83 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -624,7 +624,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit val desugared = if (protoFormals.length == 1 && params.length != 1 && ptIsCorrectProduct(protoFormals.head)) { - desugar.makeUnaryCaseLambda(params, fnBody) + desugar.makeTupledFunction(params, fnBody) } else { val inferredParams: List[untpd.ValDef] = diff --git a/tests/run/function-arity.scala b/tests/run/function-arity.scala new file mode 100644 index 000000000000..6d7e5bce10fb --- /dev/null +++ b/tests/run/function-arity.scala @@ -0,0 +1,8 @@ +object Test { + class T[A] { def foo(f: (=> A) => Int) = f(???) } + + def main(args: Array[String]): Unit = { + new T[(Int, Int)].foo((ii) => 0) + new T[(Int, Int)].foo((x, y) => 0) // check that this does not run into ??? + } +}