From 574a148fd561a793ee522c2be18ee02214236d80 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 16 Mar 2014 12:39:56 +0100 Subject: Added auto-tupling. Auto-tupling should satisfy the following spec. 1. An application `f(args)` where `f` is a non-overloaded method which has a single, non-repeated parameter as its first parameter list and where args consists of two or more arguments is expanded to `f((args))`. 2. A constructor pattern `C(args)` where `C.unapply` is a non-overloaded method which has a single, non-repeated parameter as its first parameter list and where args consists of two or more arguments is expanded to `C((args))`. Auto-tupling can be disabled by language feature "noAutoTupling". Conflicts: test/dotc/tests.scala --- src/dotty/tools/dotc/typer/Applications.scala | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/dotty/tools/dotc/typer/Applications.scala') diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index feaf678a2..4d26532d6 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -434,8 +434,17 @@ trait Applications extends Compatibility { self: Typer => def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = { def realApply(implicit ctx: Context): Tree = track("realApply") { - val proto = new FunProto(tree.args, pt, this) + var proto = new FunProto(tree.args, pt, this) val fun1 = typedExpr(tree.fun, proto) + + // Warning: The following line is dirty and fragile. We record that auto-tupling was demanded as + // a side effect in adapt. If it was, we assume the tupled proto-type in the rest of the application. + // This crucially relies on he fact that `proto` is used only in a single call of `adapt`, + // otherwise we would get possible cross-talk between different `adapt` calls using the same + // prototype. A cleaner alternative would be to return a modified prototype from `adapt` together with + // a modified tree but this would be more convoluted and less efficient. + if (proto.isTupled) proto = proto.tupled + methPart(fun1).tpe match { case funRef: TermRef => tryEither { implicit ctx => @@ -676,7 +685,10 @@ trait Applications extends Compatibility { self: Typer => var argTypes = unapplyArgs(unapplyApp.tpe) for (argType <- argTypes) assert(!argType.isInstanceOf[TypeBounds], unapplyApp.tpe.show) val bunchedArgs = argTypes match { - case argType :: Nil if argType.isRepeatedParam => untpd.SeqLiteral(args) :: Nil + case argType :: Nil => + if (argType.isRepeatedParam) untpd.SeqLiteral(args) :: Nil + else if (args.lengthCompare(1) > 0 && ctx.canAutoTuple) untpd.Tuple(args) :: Nil + else args case _ => args } if (argTypes.length != bunchedArgs.length) { -- cgit v1.2.3