Skip to content

Commit 7d2c5e1

Browse files
committed
Sema: Don't 'tuple splat' parameter lists with @autoclosure parameters
Fixes <https://bugs.swift.org/browse/SR-9991>.
1 parent 0502f3b commit 7d2c5e1

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,10 +1182,11 @@ static bool isSingleTupleParam(ASTContext &ctx,
11821182
return false;
11831183

11841184
const auto &param = params.front();
1185-
if (param.isVariadic() || param.isInOut())
1185+
if (param.isVariadic() || param.isInOut() || param.hasLabel())
11861186
return false;
11871187

11881188
auto paramType = param.getPlainType();
1189+
11891190
// Support following case which was allowed until 5:
11901191
//
11911192
// func bar(_: (Int, Int) -> Void) {}
@@ -1195,11 +1196,9 @@ static bool isSingleTupleParam(ASTContext &ctx,
11951196
if (!ctx.isSwiftVersionAtLeast(5))
11961197
paramType = paramType->lookThroughAllOptionalTypes();
11971198

1198-
// Parameter should not have a label and be either a tuple,
1199-
// type variable or a dependent member, which might later be
1200-
// assigned (or resolved to) a tuple type, e.g. opened generic parameter.
1201-
return !param.hasLabel() &&
1202-
(paramType->is<TupleType>() || paramType->isTypeVariableOrMember());
1199+
// Parameter type should either a tuple or something that can become a
1200+
// tuple later on.
1201+
return (paramType->is<TupleType>() || paramType->isTypeVariableOrMember());
12031202
}
12041203

12051204
/// Attempt to fix missing arguments by introducing type variables
@@ -1359,7 +1358,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
13591358
return false;
13601359

13611360
for (auto param : params)
1362-
if (param.isVariadic() || param.isInOut())
1361+
if (param.isVariadic() || param.isInOut() || param.isAutoClosure())
13631362
return false;
13641363

13651364
return true;

test/Constraints/tuple_arguments.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,3 +1718,23 @@ func rdar48443263() {
17181718
foo(s2, fn) // expected-error {{cannot convert value of type '() -> Void' to expected argument type '(_) -> Void'}}
17191719
}
17201720
}
1721+
1722+
func autoclosureSplat() {
1723+
func takeFn<T>(_: (T) -> ()) {}
1724+
1725+
takeFn { (fn: @autoclosure () -> Int) in }
1726+
// This type checks because we find a solution T:= @escaping () -> Int and
1727+
// wrap the closure in a function conversion.
1728+
1729+
takeFn { (fn: @autoclosure () -> Int, x: Int) in }
1730+
// expected-error@-1 {{contextual closure type '(_) -> ()' expects 1 argument, but 2 were used in closure body}}
1731+
1732+
takeFn { (fn: @autoclosure @escaping () -> Int) in }
1733+
// FIXME: It looks like matchFunctionTypes() does not check @autoclosure at all.
1734+
// Perhaps this is intentional, but we should document it eventually. In the
1735+
// interim, this test serves as "documentation"; if it fails, please investigate why
1736+
// instead of changing the test.
1737+
1738+
takeFn { (fn: @autoclosure @escaping () -> Int, x: Int) in }
1739+
// expected-error@-1 {{contextual closure type '(_) -> ()' expects 1 argument, but 2 were used in closure body}}
1740+
}

0 commit comments

Comments
 (0)