@@ -267,6 +267,7 @@ matchCallArguments(SmallVectorImpl<AnyFunctionType::Param> &args,
267267 // Local function that retrieves the next unclaimed argument with the given
268268 // name (which may be empty). This routine claims the argument.
269269 auto claimNextNamed = [&](unsigned &nextArgIdx, Identifier paramLabel,
270+ Optional<unsigned > paramIdx,
270271 bool ignoreNameMismatch,
271272 bool forVariadic = false ) -> Optional<unsigned > {
272273 // Skip over any claimed arguments.
@@ -276,6 +277,47 @@ matchCallArguments(SmallVectorImpl<AnyFunctionType::Param> &args,
276277 if (numClaimedArgs == numArgs)
277278 return None;
278279
280+ // / When we determine which argument is bound to unlabeled parameter,
281+ // / consider still unbounded parameter which is prior to current parameter.
282+ // / In order not to intersect binding position that remaining parameter will
283+ // / bind later, skip a unlabeled argument as much as it can.
284+ // /
285+ // / For example:
286+ // / @code
287+ // / func f(aa: Int, _ bb: Int) {}
288+ // / f(0, 1)
289+ // / @endcode
290+ // / Choice argument[1] for parameter[1] so that parameter[0] will be bounded
291+ // / to argument[0] later.
292+ // /
293+ // / Because variadics parameter can be bounded with more than one arguments,
294+ // / they don't this.
295+ if (paramLabel.empty () && paramIdx && !forVariadic &&
296+ !params[*paramIdx].isVariadic ()) {
297+ unsigned unboundedParamCount = 0 ;
298+ for (unsigned pi = 0 ; pi < *paramIdx; pi++) {
299+ if (parameterBindings[pi].empty ()) {
300+ if (params[pi].isVariadic () || paramInfo.hasDefaultArgument (pi))
301+ continue ;
302+
303+ unboundedParamCount++;
304+ }
305+ }
306+
307+ unsigned keepedArgCount = 0 ;
308+ for (unsigned ai = nextArgIdx; ai < numArgs; ai++) {
309+ if (claimedArgs[ai])
310+ continue ;
311+
312+ nextArgIdx = std::max (nextArgIdx, ai);
313+
314+ if (keepedArgCount >= unboundedParamCount) {
315+ break ;
316+ }
317+ keepedArgCount++;
318+ }
319+ }
320+
279321 // Go hunting for an unclaimed argument whose name does match.
280322 Optional<unsigned > claimedWithSameName;
281323 for (unsigned i = nextArgIdx; i != numArgs; ++i) {
@@ -368,8 +410,8 @@ matchCallArguments(SmallVectorImpl<AnyFunctionType::Param> &args,
368410 // Handle variadic parameters.
369411 if (param.isVariadic ()) {
370412 // Claim the next argument with the name of this parameter.
371- auto claimed =
372- claimNextNamed (nextArgIdx, param. getLabel (), ignoreNameMismatch);
413+ auto claimed = claimNextNamed (nextArgIdx, param. getLabel (), paramIdx,
414+ ignoreNameMismatch);
373415
374416 // If there was no such argument, leave the parameter unfulfilled.
375417 if (!claimed) {
@@ -390,8 +432,10 @@ matchCallArguments(SmallVectorImpl<AnyFunctionType::Param> &args,
390432 {
391433 nextArgIdx = *claimed;
392434 // Claim any additional unnamed arguments.
393- while (
394- (claimed = claimNextNamed (nextArgIdx, Identifier (), false , true ))) {
435+ while ((claimed = claimNextNamed (
436+ nextArgIdx, /* paramLabel=*/ Identifier (), /* paramIdx=*/ None,
437+ /* ignoreNameMismatch=*/ false ,
438+ /* forVariadic=*/ true ))) {
395439 parameterBindings[paramIdx].push_back (*claimed);
396440 }
397441 }
@@ -401,8 +445,8 @@ matchCallArguments(SmallVectorImpl<AnyFunctionType::Param> &args,
401445 }
402446
403447 // Try to claim an argument for this parameter.
404- if (auto claimed =
405- claimNextNamed (nextArgIdx, param. getLabel (), ignoreNameMismatch)) {
448+ if (auto claimed = claimNextNamed (nextArgIdx, param. getLabel (), paramIdx,
449+ ignoreNameMismatch)) {
406450 parameterBindings[paramIdx].push_back (*claimed);
407451 return ;
408452 }
0 commit comments