From 40e7cab7a22a8531bdd310bfb57fda51b798c690 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Fri, 11 May 2012 16:00:54 +0200 Subject: Fix SI-5009: case-class copy method now eta-expands over higher parameter lists. Example: Given case class C(a: Int)(b: Int) if you call (new C(1)(2)).copy(a = 10)), you get a function (f: Int => C) such that (f.apply(20)) yields a (new C(10)(20)). --- .../scala/tools/nsc/typechecker/Unapplies.scala | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala index 1ebcea4a07..3d9453d8cd 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala @@ -210,13 +210,25 @@ trait Unapplies extends ast.TreeDSL // and re-added in ``finishWith'' in the namer. def paramWithDefault(vd: ValDef) = treeCopy.ValDef(vd, vd.mods | DEFAULTPARAM, vd.name, atPos(vd.pos.focus)(TypeTree() setOriginal vd.tpt), toIdent(vd)) - - val paramss = mmap(cparamss)(paramWithDefault) - val classTpe = classType(cdef, tparams) + + val (copyParamss, funParamss) = cparamss match { + case Nil => (Nil, Nil) + case ps :: pss => + (List(ps.map(paramWithDefault)), mmap(pss)(p => copyUntyped[ValDef](p).copy(rhs = EmptyTree))) + } + + val classTpe = classType(cdef, tparams) + val bodyTpe = funParamss.foldRight(classTpe)((params, restp) => gen.scalaFunctionConstr(params.map(_.tpt), restp)) + + val argss = copyParamss match { + case Nil => Nil + case ps :: Nil => mmap(ps :: funParamss)(toIdent) + } + val body = funParamss.foldRight(New(classTpe, argss): Tree)(Function) Some(atPos(cdef.pos.focus)( - DefDef(Modifiers(SYNTHETIC), nme.copy, tparams, paramss, classTpe, - New(classTpe, mmap(paramss)(toIdent))) + DefDef(Modifiers(SYNTHETIC), nme.copy, tparams, copyParamss, bodyTpe, + body) )) } } -- cgit v1.2.3