Skip to content

Commit 21a1d90

Browse files
[CSSimplify] Increase score for closure argument when in a call autoclosure context to avoid ambiguity
1 parent b7a6bcb commit 21a1d90

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,6 +1347,17 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
13471347
auto *fnType = paramTy->castTo<FunctionType>();
13481348
auto *argExpr = getArgumentExpr(locator.getAnchor(), argIdx);
13491349

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+
13501361
// If the argument is not marked as @autoclosure or
13511362
// this is Swift version >= 5 where forwarding is not allowed,
13521363
// argument would always be wrapped into an implicit closure
@@ -2211,6 +2222,20 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
22112222
auto func1Param = func1Params[i];
22122223
auto func2Param = func2Params[i];
22132224

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+
22142239
// Variadic bit must match.
22152240
if (func1Param.isVariadic() != func2Param.isVariadic()) {
22162241
if (!(shouldAttemptFixes() && func2Param.isVariadic()))

0 commit comments

Comments
 (0)