@@ -1347,6 +1347,17 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
1347
1347
auto *fnType = paramTy->castTo <FunctionType>();
1348
1348
auto *argExpr = getArgumentExpr (locator.getAnchor (), argIdx);
1349
1349
1350
+ // If this is a call to a function with a closure argument and the
1351
+ // parameter is an autoclosure, let's just increment the score here
1352
+ // so situations like bellow are not ambiguous.
1353
+ // func f<T>(_: () -> T) {}
1354
+ // func f<T>(_: @autoclosure () -> T) {}
1355
+ //
1356
+ // f { } // OK
1357
+ if (isExpr<ClosureExpr>(argExpr)) {
1358
+ cs.increaseScore (SK_FunctionConversion);
1359
+ }
1360
+
1350
1361
// If the argument is not marked as @autoclosure or
1351
1362
// this is Swift version >= 5 where forwarding is not allowed,
1352
1363
// argument would always be wrapped into an implicit closure
@@ -2211,6 +2222,20 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
2211
2222
auto func1Param = func1Params[i];
2212
2223
auto func2Param = func2Params[i];
2213
2224
2225
+ // Increase the score if matching an autoclosure parameter to an function
2226
+ // type, so we enforce that non-autoclosure overloads are preferred.
2227
+ //
2228
+ // func autoclosure(f: () -> Int) { }
2229
+ // func autoclosure(f: @autoclosure () -> Int) { }
2230
+ //
2231
+ // let _ = autoclosure as (() -> (Int)) -> () // non-autoclosure preferred
2232
+ //
2233
+ if (func1Param.isAutoClosure () &&
2234
+ (!func2Param.isAutoClosure () &&
2235
+ func2Param.getPlainType ()->is <FunctionType>())) {
2236
+ increaseScore (SK_FunctionConversion);
2237
+ }
2238
+
2214
2239
// Variadic bit must match.
2215
2240
if (func1Param.isVariadic () != func2Param.isVariadic ()) {
2216
2241
if (!(shouldAttemptFixes () && func2Param.isVariadic ()))
0 commit comments