@@ -116,6 +116,13 @@ static void determineBestChoicesInContext(
116116 if (!argumentList || cs.containsIDEInspectionTarget (argumentList))
117117 return ;
118118
119+ SmallVector<FunctionType::Param, 8 > argsWithLabels;
120+ {
121+ argsWithLabels.append (argFuncType->getParams ().begin (),
122+ argFuncType->getParams ().end ());
123+ FunctionType::relabelParams (argsWithLabels, argumentList);
124+ }
125+
119126 SmallVector<SmallVector<std::pair<Type, /* fromLiteral=*/ bool >, 2 >, 2 >
120127 candidateArgumentTypes;
121128 candidateArgumentTypes.resize (argFuncType->getNumParams ());
@@ -159,6 +166,27 @@ static void determineBestChoicesInContext(
159166 resultTypes.push_back (resultType);
160167 }
161168
169+ // Match arguments to the given overload choice.
170+ auto matchArguments =
171+ [&](OverloadChoice choice,
172+ FunctionType *overloadType) -> Optional<MatchCallArgumentResult> {
173+ auto *decl = choice.getDeclOrNull ();
174+ assert (decl);
175+
176+ auto hasAppliedSelf =
177+ decl->hasCurriedSelf () &&
178+ doesMemberRefApplyCurriedSelf (choice.getBaseType (), decl);
179+
180+ ParameterListInfo paramListInfo (overloadType->getParams (), decl,
181+ hasAppliedSelf);
182+
183+ MatchCallArgumentListener listener;
184+ return matchCallArguments (argsWithLabels, overloadType->getParams (),
185+ paramListInfo,
186+ argumentList->getFirstTrailingClosureIndex (),
187+ /* allow fixes*/ false , listener, None);
188+ };
189+
162190 // The choice with the best score.
163191 double bestScore = 0.0 ;
164192 SmallVector<std::pair<Constraint *, double >, 2 > favoredChoices;
@@ -182,27 +210,35 @@ static void determineBestChoicesInContext(
182210 return ;
183211 }
184212
185- ParameterListInfo paramListInfo (
186- overloadType->getParams (), decl,
187- hasAppliedSelf (cs, choice->getOverloadChoice ()));
213+ auto matchings =
214+ matchArguments (choice->getOverloadChoice (), overloadType);
215+ if (!matchings)
216+ return ;
188217
189218 double score = 0.0 ;
190- for (unsigned i = 0 , n = overloadType->getNumParams (); i != n; ++i) {
191- const auto ¶m = overloadType->getParams ()[i];
192-
193- if (i >= candidateArgumentTypes.size ()) {
194- // If parameter has a default - continue matching,
195- // all of the subsequence parameters should have defaults
196- // as well, if they don't the overload choice in not viable.
197- if (paramListInfo.hasDefaultArgument (i))
198- continue ;
219+ for (unsigned paramIdx = 0 , n = overloadType->getNumParams ();
220+ paramIdx != n; ++paramIdx) {
221+ const auto ¶m = overloadType->getParams ()[paramIdx];
222+
223+ auto argIndices = matchings->parameterBindings [paramIdx];
224+ switch (argIndices.size ()) {
225+ case 0 :
226+ // Current parameter is defaulted.
227+ continue ;
228+
229+ case 1 :
230+ // One-to-one match between argument and parameter.
231+ break ;
199232
200- // Early return because this overload choice is not viable
201- // without default value for the current parameter .
233+ default :
234+ // Cannot deal with multiple possible matchings at the moment .
202235 return ;
203236 }
204237
205- if (candidateArgumentTypes[i].empty ())
238+ auto argIdx = argIndices.front ();
239+
240+ // Looks like there is nothing know about the argument.
241+ if (candidateArgumentTypes[argIdx].empty ())
206242 continue ;
207243
208244 const auto paramFlags = param.getParameterFlags ();
@@ -220,9 +256,6 @@ static void determineBestChoicesInContext(
220256 if (paramType->is <FunctionType>())
221257 continue ;
222258
223- if (candidateArgumentTypes[i].empty ())
224- continue ;
225-
226259 // Check protocol requirement(s) if this parameter is a
227260 // generic parameter type.
228261 GenericSignature::RequiredProtocols protocolRequirements;
@@ -248,11 +281,11 @@ static void determineBestChoicesInContext(
248281 // all bound concrete types, we consider this is mismatch
249282 // at this parameter position and remove the overload choice
250283 // from consideration.
251-
252284 double bestCandidateScore = 0 ;
253- llvm::BitVector mismatches (candidateArgumentTypes[i ].size ());
285+ llvm::BitVector mismatches (candidateArgumentTypes[argIdx ].size ());
254286
255- for (unsigned candidateIdx : indices (candidateArgumentTypes[i])) {
287+ for (unsigned candidateIdx :
288+ indices (candidateArgumentTypes[argIdx])) {
256289 // If one of the candidates matched exactly there is no reason
257290 // to continue checking.
258291 if (bestCandidateScore == 1 )
@@ -262,7 +295,7 @@ static void determineBestChoicesInContext(
262295 bool isLiteralDefault;
263296
264297 std::tie (candidateType, isLiteralDefault) =
265- candidateArgumentTypes[i ][candidateIdx];
298+ candidateArgumentTypes[argIdx ][candidateIdx];
266299
267300 // `inout` parameter accepts only l-value argument.
268301 if (paramFlags.isInOut () && !candidateType->is <LValueType>()) {
0 commit comments