@@ -172,9 +172,67 @@ void forEachDisjunctionChoice(
172
172
}
173
173
}
174
174
175
- static bool isOverloadedDeclRef (Constraint *disjunction) {
175
+ static OverloadedDeclRefExpr * isOverloadedDeclRef (Constraint *disjunction) {
176
176
assert (disjunction->getKind () == ConstraintKind::Disjunction);
177
- return disjunction->getLocator ()->directlyAt <OverloadedDeclRefExpr>();
177
+
178
+ auto *locator = disjunction->getLocator ();
179
+ if (locator->getPath ().empty ())
180
+ return getAsExpr<OverloadedDeclRefExpr>(locator->getAnchor ());
181
+ return nullptr ;
182
+ }
183
+
184
+ // / This maintains an "old hack" behavior where overloads of some
185
+ // / `OverloadedDeclRef` calls were favored purely based on number of
186
+ // / argument and (non-defaulted) parameters matching.
187
+ static void findFavoredChoicesBasedOnArity (
188
+ ConstraintSystem &cs, Constraint *disjunction, ArgumentList *argumentList,
189
+ llvm::function_ref<void (Constraint *)> favoredChoice) {
190
+ auto *ODRE = isOverloadedDeclRef (disjunction);
191
+ if (!ODRE)
192
+ return ;
193
+
194
+ if (llvm::count_if (ODRE->getDecls (), [&argumentList](auto *choice) {
195
+ if (auto *paramList = getParameterList (choice))
196
+ return argumentList->size () == paramList->size ();
197
+ return false ;
198
+ }) > 1 )
199
+ return ;
200
+
201
+ auto isVariadicGenericOverload = [&](ValueDecl *choice) {
202
+ auto genericContext = choice->getAsGenericContext ();
203
+ if (!genericContext)
204
+ return false ;
205
+
206
+ auto *GPL = genericContext->getGenericParams ();
207
+ if (!GPL)
208
+ return false ;
209
+
210
+ return llvm::any_of (GPL->getParams (), [&](const GenericTypeParamDecl *GP) {
211
+ return GP->isParameterPack ();
212
+ });
213
+ };
214
+
215
+ bool hasVariadicGenerics = false ;
216
+ SmallVector<Constraint *> favored;
217
+
218
+ forEachDisjunctionChoice (
219
+ cs, disjunction,
220
+ [&](Constraint *choice, ValueDecl *decl, FunctionType *overloadType) {
221
+ if (isVariadicGenericOverload (decl))
222
+ hasVariadicGenerics = true ;
223
+
224
+ if (overloadType->getNumParams () == argumentList->size () ||
225
+ llvm::count_if (*getParameterList (decl), [](auto *param) {
226
+ return !param->isDefaultArgument ();
227
+ }) == argumentList->size ())
228
+ favored.push_back (choice);
229
+ });
230
+
231
+ if (hasVariadicGenerics)
232
+ return ;
233
+
234
+ for (auto *choice : favored)
235
+ favoredChoice (choice);
178
236
}
179
237
180
238
} // end anonymous namespace
@@ -193,9 +251,6 @@ static Constraint *determineBestChoicesInContext(
193
251
favoredChoicesPerDisjunction;
194
252
195
253
for (auto *disjunction : disjunctions) {
196
- if (!isSupportedDisjunction (disjunction))
197
- continue ;
198
-
199
254
auto applicableFn =
200
255
getApplicableFnConstraint (cs.getConstraintGraph (), disjunction);
201
256
@@ -218,6 +273,25 @@ static Constraint *determineBestChoicesInContext(
218
273
}
219
274
}
220
275
276
+ // This maintains an "old hack" behavior where overloads
277
+ // of `OverloadedDeclRef` calls were favored purely
278
+ // based on arity of arguments and parameters matching.
279
+ {
280
+ findFavoredChoicesBasedOnArity (
281
+ cs, disjunction, argumentList, [&](Constraint *choice) {
282
+ favoredChoicesPerDisjunction[disjunction].push_back (choice);
283
+ });
284
+
285
+ if (!favoredChoicesPerDisjunction[disjunction].empty ()) {
286
+ disjunctionScores[disjunction] = 0.01 ;
287
+ bestOverallScore = std::max (bestOverallScore, 0.01 );
288
+ continue ;
289
+ }
290
+ }
291
+
292
+ if (!isSupportedDisjunction (disjunction))
293
+ continue ;
294
+
221
295
SmallVector<FunctionType::Param, 8 > argsWithLabels;
222
296
{
223
297
argsWithLabels.append (argFuncType->getParams ().begin (),
0 commit comments