Allow a variadic parameter anywhere in the parameter list.

Requiring a variadic parameter to come at the end of the parameter
list is an old restriction that makes no sense nowadays, and which we
had all thought we had already lifted. It made variadic parameters
unusable with trailing closures or defaulted arguments, and made our
new print() design unimplementable.

Remove this restriction, replacing it with a less onerous and slightly
less silly restriction that we not have more than one variadic
parameter in a given parameter clause. Fixes rdar://problem/20127197.

Swift SVN r30542
This commit is contained in:
Doug Gregor
2015-07-23 18:45:29 +00:00
parent fdc927e8d7
commit f00e5bc6ab
36 changed files with 388 additions and 255 deletions

View File

@@ -798,7 +798,8 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
}
// Check each of the elements.
bool hasVarArg = false;
bool hasVariadic = false;
unsigned variadicIdx = sources.size();
for (unsigned idx2 = 0, n = sources.size(); idx2 != n; ++idx2) {
// Default-initialization always allowed for conversions.
if (sources[idx2] == TupleShuffleExpr::DefaultInitialize) {
@@ -806,8 +807,10 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
}
// Variadic arguments handled below.
if (sources[idx2] == TupleShuffleExpr::FirstVariadic) {
hasVarArg = true;
if (sources[idx2] == TupleShuffleExpr::Variadic) {
assert(!hasVariadic && "Multiple variadic parameters");
hasVariadic = true;
variadicIdx = idx2;
continue;
}
@@ -831,8 +834,8 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
}
// If we have variadic arguments to check, do so now.
if (hasVarArg) {
const auto &elt2 = tuple2->getElements().back();
if (hasVariadic) {
const auto &elt2 = tuple2->getElements()[variadicIdx];
auto eltType2 = elt2.getVarargBaseTy();
for (unsigned idx1 : variadicArguments) {