@@ -724,41 +724,70 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
724724 */
725725 var fnBody = tree.body
726726
727+ /** A map from parameter names to unique positions where the parameter
728+ * appears in the argument list of an application.
729+ */
730+ var paramIndex = Map [Name , Int ]()
731+
732+ /** If parameter `param` appears exactly once as an argument in `args`,
733+ * the singleton list consisting of its position in `args`, otherwise `Nil`.
734+ */
735+ def paramIndices (param : untpd.ValDef , args : List [untpd.Tree ], start : Int ): List [Int ] = args match {
736+ case arg :: args1 =>
737+ if (refersTo(arg, param))
738+ if (paramIndices(param, args1, start + 1 ).isEmpty) start :: Nil
739+ else Nil
740+ else paramIndices(param, args1, start + 1 )
741+ case _ => Nil
742+ }
743+
727744 /** If function is of the form
728- * (x1, ..., xN) => f(x1, ..., XN)
729- * the type of `f`, otherwise NoType. (updates `fnBody` as a side effect).
745+ * (x1, ..., xN) => f(... x1, ..., XN, ...)
746+ * where each `xi` occurs exactly once in the argument list of `f` (in
747+ * any order), the type of `f`, otherwise NoType.
748+ * Updates `fnBody` and `paramIndex` as a side effect.
749+ * @post: If result exists, `paramIndex` is defined for the name of
750+ * every parameter in `params`.
730751 */
731752 def calleeType : Type = fnBody match {
732- case Apply (expr, args) if (args corresponds params)(refersTo) =>
733- expr match {
734- case untpd.TypedSplice (expr1) =>
735- expr1.tpe
736- case _ =>
737- val protoArgs = args map (_ withType WildcardType )
738- val callProto = FunProto (protoArgs, WildcardType , this )
739- val expr1 = typedExpr(expr, callProto)
740- fnBody = cpy.Apply (fnBody)(untpd.TypedSplice (expr1), args)
741- expr1.tpe
742- }
753+ case Apply (expr, args) =>
754+ paramIndex = {
755+ for (param <- params; idx <- paramIndices(param, args, 0 ))
756+ yield param.name -> idx
757+ }.toMap
758+ if (paramIndex.size == params.length)
759+ expr match {
760+ case untpd.TypedSplice (expr1) =>
761+ expr1.tpe
762+ case _ =>
763+ val protoArgs = args map (_ withType WildcardType )
764+ val callProto = FunProto (protoArgs, WildcardType , this )
765+ val expr1 = typedExpr(expr, callProto)
766+ fnBody = cpy.Apply (fnBody)(untpd.TypedSplice (expr1), args)
767+ expr1.tpe
768+ }
769+ else NoType
743770 case _ =>
744771 NoType
745772 }
746773
747774 /** Two attempts: First, if expected type is fully defined pick this one.
748775 * Second, if function is of the form
749- * (x1, ..., xN) => f(x1, ..., XN)
750- * and f has a method type MT, pick the corresponding parameter type in MT,
751- * if this one is fully defined.
776+ * (x1, ..., xN) => f(... x1, ..., XN, ...)
777+ * where each `xi` occurs exactly once in the argument list of `f` (in
778+ * any order), and f has a method type MT, pick the corresponding parameter
779+ * type in MT, if this one is fully defined.
752780 * If both attempts fail, issue a "missing parameter type" error.
753781 */
754782 def inferredParamType (param : untpd.ValDef , formal : Type ): Type = {
755783 if (isFullyDefined(formal, ForceDegree .noBottom)) return formal
756784 calleeType.widen match {
757785 case mtpe : MethodType =>
758- val pos = params indexWhere (_.name == param.name)
786+ val pos = paramIndex( param.name)
759787 if (pos < mtpe.paramInfos.length) {
760788 val ptype = mtpe.paramInfos(pos)
761- if (isFullyDefined(ptype, ForceDegree .noBottom)) return ptype
789+ if (isFullyDefined(ptype, ForceDegree .noBottom) && ! ptype.isRepeatedParam)
790+ return ptype
762791 }
763792 case _ =>
764793 }
0 commit comments