Skip to content

Commit dd84310

Browse files
committed
Sema: SE-0110 tuple splatting should not implode argument list with varargs
Fixes <https://bugs.swift.org/browse/SR-9470>.
1 parent dbb8e3b commit dd84310

File tree

3 files changed

+31
-11
lines changed

3 files changed

+31
-11
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,17 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
11731173
!params[0].isVariadic());
11741174
};
11751175

1176+
auto canImplodeParams = [&](ArrayRef<AnyFunctionType::Param> params) {
1177+
if (params.size() == 1)
1178+
return false;
1179+
1180+
for (auto param : params)
1181+
if (param.isVariadic() || param.isInOut())
1182+
return false;
1183+
1184+
return true;
1185+
};
1186+
11761187
auto implodeParams = [&](SmallVectorImpl<AnyFunctionType::Param> &params) {
11771188
auto input = AnyFunctionType::composeInput(getASTContext(), params,
11781189
/*canonicalVararg=*/false);
@@ -1193,21 +1204,18 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
11931204

11941205
if (last != path.rend()) {
11951206
if (last->getKind() == ConstraintLocator::ApplyArgToParam) {
1196-
if (isSingleParam(func2Params)) {
1197-
if (!isSingleParam(func1Params)) {
1198-
implodeParams(func1Params);
1199-
}
1200-
} else if (getASTContext().isSwiftVersionAtLeast(4)
1201-
&& !getASTContext().isSwiftVersionAtLeast(5)
1202-
&& !isSingleParam(func2Params)) {
1207+
if (isSingleParam(func2Params) &&
1208+
canImplodeParams(func1Params)) {
1209+
implodeParams(func1Params);
1210+
} else if (!getASTContext().isSwiftVersionAtLeast(5) &&
1211+
isSingleParam(func1Params) &&
1212+
canImplodeParams(func2Params)) {
12031213
auto *simplified = locator.trySimplifyToExpr();
12041214
// We somehow let tuple unsplatting function conversions
12051215
// through in some cases in Swift 4, so let's let that
12061216
// continue to work, but only for Swift 4.
12071217
if (simplified && isa<DeclRefExpr>(simplified)) {
1208-
if (isSingleParam(func1Params)) {
1209-
implodeParams(func2Params);
1210-
}
1218+
implodeParams(func2Params);
12111219
}
12121220
}
12131221
}

test/Compatibility/tuple_arguments_4.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1677,3 +1677,9 @@ class Mappable<T> {
16771677

16781678
let x = Mappable(())
16791679
_ = x.map { (_: Void) in return () }
1680+
1681+
// https://bugs.swift.org/browse/SR-9470
1682+
do {
1683+
func f(_: Int...) {}
1684+
let _ = [(1, 2, 3)].map(f) // expected-error {{cannot invoke 'map' with an argument list of type '((Int...) -> ())'}}
1685+
}

test/Constraints/tuple_arguments.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1679,4 +1679,10 @@ class Mappable<T> {
16791679
}
16801680

16811681
let x = Mappable(())
1682-
_ = x.map { (_: Void) in return () }
1682+
_ = x.map { (_: Void) in return () }
1683+
1684+
// https://bugs.swift.org/browse/SR-9470
1685+
do {
1686+
func f(_: Int...) {}
1687+
let _ = [(1, 2, 3)].map(f) // expected-error {{cannot invoke 'map' with an argument list of type '((Int...) -> ())'}}
1688+
}

0 commit comments

Comments
 (0)