Skip to content

Commit c5cdd70

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 b8ff7f1 commit c5cdd70

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
@@ -1141,6 +1141,17 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
11411141
!params[0].isVariadic());
11421142
};
11431143

1144+
auto canImplodeParams = [&](ArrayRef<AnyFunctionType::Param> params) {
1145+
if (params.size() == 1)
1146+
return false;
1147+
1148+
for (auto param : params)
1149+
if (param.isVariadic() || param.isInOut())
1150+
return false;
1151+
1152+
return true;
1153+
};
1154+
11441155
auto implodeParams = [&](SmallVectorImpl<AnyFunctionType::Param> &params) {
11451156
auto input = AnyFunctionType::composeInput(getASTContext(), params,
11461157
/*canonicalVararg=*/false);
@@ -1161,21 +1172,18 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
11611172

11621173
if (last != path.rend()) {
11631174
if (last->getKind() == ConstraintLocator::ApplyArgToParam) {
1164-
if (isSingleParam(func2Params)) {
1165-
if (!isSingleParam(func1Params)) {
1166-
implodeParams(func1Params);
1167-
}
1168-
} else if (getASTContext().isSwiftVersionAtLeast(4)
1169-
&& !getASTContext().isSwiftVersionAtLeast(5)
1170-
&& !isSingleParam(func2Params)) {
1175+
if (isSingleParam(func2Params) &&
1176+
canImplodeParams(func1Params)) {
1177+
implodeParams(func1Params);
1178+
} else if (!getASTContext().isSwiftVersionAtLeast(5) &&
1179+
isSingleParam(func1Params) &&
1180+
canImplodeParams(func2Params)) {
11711181
auto *simplified = locator.trySimplifyToExpr();
11721182
// We somehow let tuple unsplatting function conversions
11731183
// through in some cases in Swift 4, so let's let that
11741184
// continue to work, but only for Swift 4.
11751185
if (simplified && isa<DeclRefExpr>(simplified)) {
1176-
if (isSingleParam(func1Params)) {
1177-
implodeParams(func2Params);
1178-
}
1186+
implodeParams(func2Params);
11791187
}
11801188
}
11811189
}

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)