Skip to content

Commit

Permalink
Merge pull request #29735 from owenv/multiple-varargs
Browse files Browse the repository at this point in the history
[SE-0284] Allow Multiple Variadic Parameters in Functions, Subscripts, and Initializers
  • Loading branch information
owenv committed Sep 5, 2020
2 parents ea5604e + 9708247 commit c6a266e
Show file tree
Hide file tree
Showing 8 changed files with 257 additions and 22 deletions.
4 changes: 2 additions & 2 deletions include/swift/AST/DiagnosticsParse.def
Expand Up @@ -882,8 +882,6 @@ ERROR(expected_parameter_colon,PointsToFirstBadToken,
"expected ':' following argument label and parameter name", ())
ERROR(expected_assignment_instead_of_comparison_operator,none,
"expected '=' instead of '==' to assign default value for parameter", ())
ERROR(multiple_parameter_ellipsis,none,
"only a single variadic parameter '...' is permitted", ())
ERROR(parameter_vararg_default,none,
"variadic parameter cannot have a default value", ())
ERROR(parameter_specifier_as_attr_disallowed,none,
Expand Down Expand Up @@ -916,6 +914,8 @@ ERROR(initializer_as_typed_pattern,none,

ERROR(unlabeled_parameter_following_variadic_parameter,none,
"a parameter following a variadic parameter requires a label", ())
ERROR(closure_unlabeled_parameter_following_variadic_parameter,none,
"no parameters may follow a variadic parameter in a closure", ())

ERROR(enum_element_empty_arglist,none,
"enum element with associated values must have at least one "
Expand Down
28 changes: 13 additions & 15 deletions lib/Parse/ParsePattern.cpp
Expand Up @@ -574,7 +574,6 @@ mapParsedParameters(Parser &parser,
// Collect the elements of the tuple patterns for argument and body
// parameters.
SmallVector<ParamDecl*, 4> elements;
SourceLoc ellipsisLoc;

for (auto &param : params) {
// Whether the provided name is API by default depends on the parameter
Expand Down Expand Up @@ -625,27 +624,26 @@ mapParsedParameters(Parser &parser,
}

// Warn when an unlabeled parameter follows a variadic parameter
if (ellipsisLoc.isValid() && elements.back()->isVariadic() &&
param.FirstName.empty()) {
parser.diagnose(param.FirstNameLoc,
diag::unlabeled_parameter_following_variadic_parameter);
if (!elements.empty() && elements.back()->isVariadic() && argName.empty()) {
// Closure parameters can't have external labels, so use a more specific
// diagnostic.
if (paramContext == Parser::ParameterContextKind::Closure)
parser.diagnose(
param.FirstNameLoc,
diag::closure_unlabeled_parameter_following_variadic_parameter);
else
parser.diagnose(param.FirstNameLoc,
diag::unlabeled_parameter_following_variadic_parameter);
}

// If this parameter had an ellipsis, check whether it's the last parameter.
if (param.EllipsisLoc.isValid()) {
if (ellipsisLoc.isValid()) {
parser.diagnose(param.EllipsisLoc, diag::multiple_parameter_ellipsis)
.highlight(ellipsisLoc)
.fixItRemove(param.EllipsisLoc);

param.EllipsisLoc = SourceLoc();
} else if (!result->getTypeRepr()) {
// If this parameter had an ellipsis, check it has a TypeRepr.
if (param.EllipsisLoc.isValid()) {
if (!result->getTypeRepr()) {
parser.diagnose(param.EllipsisLoc, diag::untyped_pattern_ellipsis)
.highlight(result->getSourceRange());

param.EllipsisLoc = SourceLoc();
} else {
ellipsisLoc = param.EllipsisLoc;
result->setVariadic();
}
}
Expand Down
107 changes: 107 additions & 0 deletions test/Constraints/argument_matching.swift
Expand Up @@ -305,6 +305,93 @@ variadics6(x: 1, 2, 3) // expected-error{{missing argument for parameter 'z' in
variadics6(x: 1) // expected-error{{missing argument for parameter 'z' in call}}
variadics6() // expected-error{{missing argument for parameter 'z' in call}}

func variadics7(_ x: Int..., y: Int...) { }

// Using multiple variadics (in order, complete)
variadics7(1, y: 2)
variadics7(1, 2, 3, y: 4, 5, 6)
variadics7(1, 2, y: 2)
variadics7(1, y: 2, 1)

// multiple variadics, in order, some missing
variadics7(y: 1)
variadics7(1)
variadics7(y: 4, 5, 6)
variadics7(1, 2, 3)

func variadics8(x: Int..., y: Int...) { }

// multiple variadics, out of order
variadics8(y: 1, x: 2) // expected-error {{argument 'x' must precede argument 'y'}} {{12-12=x: 2, }} {{16-22=}}
variadics8(y: 1, 2, 3, x: 4) // expected-error {{argument 'x' must precede argument 'y'}} {{12-12=x: 4, }} {{22-28=}}
variadics8(y: 1, x: 2, 3, 4) // expected-error {{argument 'x' must precede argument 'y'}} {{12-12=x: 2, 3, 4, }} {{16-28=}}
variadics8(y: 1, 2, 3, x: 4, 5, 6) // expected-error {{argument 'x' must precede argument 'y'}} {{12-12=x: 4, 5, 6, }} {{22-34=}}

func variadics9(_ a: Int..., b: Int, _ c: Int...) { } // expected-note {{'variadics9(_:b:_:)' declared here}}

// multiple split variadics, in order, complete
variadics9(1, b: 2, 3)
variadics9(1, 2, 3, b: 2, 3)
variadics9(1, b: 2, 3, 2, 1)
variadics9(1, 2, 3, b: 2, 3, 2, 1)

// multiple split variadics, in order, some missing
variadics9(b: 2, 3)
variadics9(1, b: 2)
variadics9(1, 2, b: 2)
variadics9(b: 2, 3, 2, 1)

// multiple split variadics, required missing
variadics9(1) // expected-error {{missing argument for parameter 'b' in call}}

func variadics10(_ a: Int..., b: Int = 2, _ c: Int...) { }

// multiple unlabeled variadics split by defaulted param, in order, complete
variadics10(1, b: 2, 3)
variadics10(1, 2, 3, b: 2, 3)
variadics10(1, b: 2, 3, 2, 1)
variadics10(1, 2, 3, b: 2, 3, 2, 1)

// multiple unlabeled variadics split by defaulted param, in order, some missing
variadics10(1, 2, 3)
variadics10(1, 2, 3, b: 3)
variadics10(b: 3)

func variadics11(_ a: Int..., b: Bool = false, _ c: String...) { }

variadics11(1, 2, 3, b: true, "hello", "world")
variadics11(b: true, "hello", "world")
variadics11(1, 2, 3, b: true)
variadics11(b: true)
variadics11()
variadics11(1, 2, 3, "hello", "world") // expected-error 2 {{cannot convert value of type 'String' to expected argument type 'Int'}}

func variadics12(a: Int..., b: Int, c: Int...) { }

variadics12(a: 1, 2, 3, b: 4, c: 5, 6, 7)
variadics12(b: 4, c: 5, 6, 7)
variadics12(a: 1, 2, 3, b: 4)

variadics12(c: 5, 6, 7, b: 4, a: 1, 2, 3) // expected-error {{incorrect argument labels in call (have 'c:_:_:b:a:_:_:', expected 'a:b:c:')}} {{13-14=a}} {{19-19=b: }} {{22-22=c: }} {{25-28=}} {{31-34=}}


// Edge cases involving multiple trailing closures and forward matching.
func variadics13(a: Int..., b: (()->Void)...) {}

variadics13()
variadics13(a: 1, 2, 3) {} _: {} _: {}
variadics13() {} _: {} _: {}
variadics13(a: 1, 2, 3)
variadics13(a: 1, 2, 3) {}

func variadics14(a: (()->Void)..., b: (()->Void)...) {} // expected-note {{'variadics14(a:b:)' declared here}}

variadics14(a: {}, {}, b: {}, {})
variadics14(a: {}, {}) {} _: {}
variadics14 {} _: {} b: {} _: {}
variadics14 {} b: {}
variadics14 {} // expected-warning {{backward matching of the unlabeled trailing closure is deprecated; label the argument with 'b' to suppress this warning}}

func outOfOrder(_ a : Int, b: Int) {
outOfOrder(b: 42, 52) // expected-error {{unnamed argument #2 must precede argument 'b'}} {{14-14=52, }} {{19-23=}}
}
Expand Down Expand Up @@ -1336,6 +1423,26 @@ d = sub2[d] // expected-error{{missing argument label 'd:' in subscript}} {{10-1
d = sub2[d: d]
d = sub2[f: d] // expected-error{{incorrect argument label in subscript (have 'f:', expected 'd:')}} {{10-11=d}}

struct Sub3 {
subscript (a: Int..., b b: Int...) -> Int { 42 }
}

let sub3 = Sub3()
_ = sub3[1, 2, 3, b: 4, 5, 6]
_ = sub3[b: 4, 5, 6]
_ = sub3[1, 2, 3]
_ = sub3[1, c: 4] // expected-error {{incorrect argument label in subscript (have '_:c:', expected '_:b:')}}

struct Sub4 {
subscript (a: Int..., b b: Int = 0, c: Int...) -> Int { 42 }
}

let sub4 = Sub4()
_ = sub4[1, 2, 3, b: 2, 1, 2, 3]
_ = sub4[1, 2, 3, b: 2]
_ = sub4[1, 2, 3]
_ = sub4[]

// -------------------------------------------
// Closures
// -------------------------------------------
Expand Down
85 changes: 85 additions & 0 deletions test/Interpreter/multiple_varargs.swift
@@ -0,0 +1,85 @@
// RUN: %target-run-simple-swift | %FileCheck %s

// REQUIRES: executable_test

func vf(x: Int..., y: Int...) {
print(x, y)
}

vf(x: 1, 2, 3, y: 4, 5, 6)
// CHECK: [1, 2, 3] [4, 5, 6]
vf(y: 1, 2)
// CHECK: [] [1, 2]
vf(x: 3, 4)
// CHECK: [3, 4] []

func vf2(_ x: Int..., y: Int, _ z: Int...) {
print(x, y, z)
}

vf2(1, 2, 3, y: 4, 5, 6, 7)
// CHECK: [1, 2, 3] 4 [5, 6, 7]
vf2(y: 4, 5, 6, 7)
// CHECK: [] 4 [5, 6, 7]
vf2(1, 2, 3, y: 4)
// CHECK: [1, 2, 3] 4 []
vf2(y: 4)
// CHECK: [] 4 []

func vf3(_ x: Int..., y: Int = 42, _ z: Int...) {
print(x, y, z)
}

vf3(1, 2, 3, y: 4, 5, 6, 7)
// CHECK: [1, 2, 3] 4 [5, 6, 7]
vf3(y: 4, 5, 6, 7)
// CHECK: [] 4 [5, 6, 7]
vf3(1, 2, 3, y: 4)
// CHECK: [1, 2, 3] 4 []
vf3(y: 4)
// CHECK: [] 4 []

vf3()
// CHECK: [] 42 []
vf3(1, 2, 3)
// CHECK: [1, 2, 3] 42 []

func foo(a: Int..., b: Int, c: Int..., d: Int) {
print("one")
}

func foo(a: [Int], b: Int, c: [Int], d: Int) {
print("two")
}

func foo(a: Int..., b: Int, c: [Int], d: Int) {
print("three")
}

foo(a: 1, 2, 3, b: 4, c: 5, 6, 7, d: 8)
// CHECK: one
foo(a: [1, 2, 3], b: 4, c: [5, 6, 7], d: 8)
// CHECK: two
foo(a: 1, 2, 3, b: 4, c: [5, 6, 7], d: 8)
// CHECK: three

struct Baz {
init(a: Int..., b: Int...) {
print(a, b)
}

init(_ a: Int..., b: String, _ c: Int...) {
print(a, b, c)
}

subscript(a: Int..., b b: Int...) -> [Int] { a + b }
}

let baz1 = Baz(a: 1, 2, 3, b: 4, 5, 6)
// CHECK: [1, 2, 3] [4, 5, 6]

let baz2 = Baz(1, 2, 3, b: "hello, world!", 3, 2, 1)
// CHECK: [1, 2, 3] hello, world! [3, 2, 1]

print(baz1[1, 2, b: 3, 4])
// CHECK: [1, 2, 3, 4]
8 changes: 8 additions & 0 deletions test/SILGen/arguments.swift
Expand Up @@ -82,6 +82,14 @@ func variadic_arg_3(_ y: Float..., x: Int) {}
// CHECK-LABEL: sil hidden [ossa] @$ss14variadic_arg_3{{[_0-9a-zA-Z]*}}F
// CHECK: bb0([[Y:%[0-9]+]] : $Array<Float>, [[X:%[0-9]+]] : $Int):

func variadic_arg_4(_ y: Float..., x: Int...) {}
// CHECK-LABEL: sil hidden [ossa] @$ss14variadic_arg_4{{[_0-9a-zA-Z]*}}F
// CHECK: bb0([[Y:%[0-9]+]] : $Array<Float>, [[X:%[0-9]+]] : $Array<Int>):

func variadic_arg_5(a: Int, b: Float..., c: Int, d: Int...) {}
// CHECK-LABEL: sil hidden [ossa] @$ss14variadic_arg_5{{[_0-9a-zA-Z]*}}F
// CHECK: bb0([[A:%[0-9]+]] : $Int, [[B:%[0-9]+]] : $Array<Float>, [[C:%[0-9]+]] : $Int, [[D:%[0-9]+]] : $Array<Int>):

variadic_arg_3(x: i)
variadic_arg_3(f, x: i)
variadic_arg_3(f, f, f, x: i)
Expand Down
9 changes: 6 additions & 3 deletions test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
Expand Up @@ -102,13 +102,15 @@ class C <MemberDeclBlock>{<MemberDeclListItem><FunctionDecl>
@objc </Attribute><DeclModifier>private </DeclModifier>init<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>)</ParameterClause></InitializerDecl></MemberDeclListItem><MemberDeclListItem><InitializerDecl>
init!<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause><CodeBlock>{}</CodeBlock></InitializerDecl></MemberDeclListItem><MemberDeclListItem><InitializerDecl>
init?<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause><CodeBlock>{}</CodeBlock></InitializerDecl></MemberDeclListItem><MemberDeclListItem><InitializerDecl><DeclModifier>
public </DeclModifier>init<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause>throws <CodeBlock>{}</CodeBlock></InitializerDecl></MemberDeclListItem><MemberDeclListItem><DeinitializerDecl><Attribute>
public </DeclModifier>init<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause>throws <CodeBlock>{}</CodeBlock></InitializerDecl></MemberDeclListItem><MemberDeclListItem><InitializerDecl>
init<ParameterClause>(<FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier>..., </FunctionParameter><FunctionParameter>b: <SimpleTypeIdentifier>Double</SimpleTypeIdentifier>...</FunctionParameter>) </ParameterClause><CodeBlock>{}</CodeBlock></InitializerDecl></MemberDeclListItem><MemberDeclListItem><DeinitializerDecl><Attribute>

@objc </Attribute>deinit <CodeBlock>{}</CodeBlock></DeinitializerDecl></MemberDeclListItem><MemberDeclListItem><DeinitializerDecl><DeclModifier>
private </DeclModifier>deinit <CodeBlock>{}</CodeBlock></DeinitializerDecl></MemberDeclListItem><MemberDeclListItem><SubscriptDecl><DeclModifier>

internal </DeclModifier>subscript<ParameterClause>(<FunctionParameter>x: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause><ReturnClause>-> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></ReturnClause><AccessorBlock>{ <AccessorDecl>get <CodeBlock>{} </CodeBlock></AccessorDecl><AccessorDecl>set <CodeBlock>{} </CodeBlock></AccessorDecl>}</AccessorBlock></SubscriptDecl></MemberDeclListItem><MemberDeclListItem><SubscriptDecl>
subscript<ParameterClause>() </ParameterClause><ReturnClause>-> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></ReturnClause><CodeBlock>{ <ReturnStmt>return <IntegerLiteralExpr>1 </IntegerLiteralExpr></ReturnStmt>}</CodeBlock></SubscriptDecl></MemberDeclListItem><MemberDeclListItem><VariableDecl>
subscript<ParameterClause>() </ParameterClause><ReturnClause>-> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></ReturnClause><CodeBlock>{ <ReturnStmt>return <IntegerLiteralExpr>1 </IntegerLiteralExpr></ReturnStmt>}</CodeBlock></SubscriptDecl></MemberDeclListItem><MemberDeclListItem><SubscriptDecl>
subscript<ParameterClause>(<FunctionParameter>x: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier>..., </FunctionParameter><FunctionParameter>y y: <SimpleTypeIdentifier>String</SimpleTypeIdentifier>...</FunctionParameter>) </ParameterClause><ReturnClause>-> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></ReturnClause><CodeBlock>{ <ReturnStmt>return <IntegerLiteralExpr>1 </IntegerLiteralExpr></ReturnStmt>}</CodeBlock></SubscriptDecl></MemberDeclListItem><MemberDeclListItem><VariableDecl>

var <PatternBinding><IdentifierPattern>x</IdentifierPattern><TypeAnnotation>: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></TypeAnnotation><CodeBlock>{<FunctionCallExpr><IdentifierExpr>
address </IdentifierExpr><ClosureExpr>{ <FunctionCallExpr><IdentifierExpr>fatalError</IdentifierExpr>() </FunctionCallExpr>}</ClosureExpr></FunctionCallExpr><FunctionCallExpr><IdentifierExpr>
Expand Down Expand Up @@ -197,7 +199,8 @@ func foo<FunctionSignature><ParameterClause>(<FunctionParameter>_ _: <SimpleType
d _: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier><InitializerClause>= <SequenceExpr><TernaryExpr><BooleanLiteralExpr>true </BooleanLiteralExpr>? <IntegerLiteralExpr>2</IntegerLiteralExpr>: <IntegerLiteralExpr>3</IntegerLiteralExpr></TernaryExpr></SequenceExpr></InitializerClause>,</FunctionParameter><FunctionParameter><Attribute>
@objc </Attribute>e: <SimpleTypeIdentifier>X </SimpleTypeIdentifier><InitializerClause>= <BooleanLiteralExpr>true</BooleanLiteralExpr></InitializerClause>,</FunctionParameter><FunctionParameter>
f: <AttributedType>inout <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></AttributedType>,</FunctionParameter><FunctionParameter>
g: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier>...</FunctionParameter>) </ParameterClause>throws <ReturnClause>-> <DictionaryType>[<SimpleTypeIdentifier>Int</SimpleTypeIdentifier>: <SimpleTypeIdentifier>String</SimpleTypeIdentifier>] </DictionaryType></ReturnClause></FunctionSignature><CodeBlock>{}</CodeBlock></FunctionDecl><FunctionDecl>
g: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier>...,</FunctionParameter><FunctionParameter>
h: <SimpleTypeIdentifier>Bool</SimpleTypeIdentifier>...</FunctionParameter>) </ParameterClause>throws <ReturnClause>-> <DictionaryType>[<SimpleTypeIdentifier>Int</SimpleTypeIdentifier>: <SimpleTypeIdentifier>String</SimpleTypeIdentifier>] </DictionaryType></ReturnClause></FunctionSignature><CodeBlock>{}</CodeBlock></FunctionDecl><FunctionDecl>

func foo<FunctionSignature><ParameterClause>(<FunctionParameter>_ a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause>throws <ReturnClause>-> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></ReturnClause></FunctionSignature><CodeBlock>{}</CodeBlock></FunctionDecl><FunctionDecl>
func foo<FunctionSignature><ParameterClause>( <FunctionParameter>a: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></FunctionParameter>) </ParameterClause>rethrows <ReturnClause>-> <SimpleTypeIdentifier>Int </SimpleTypeIdentifier></ReturnClause></FunctionSignature><CodeBlock>{}</CodeBlock></FunctionDecl><StructDecl>
Expand Down
5 changes: 4 additions & 1 deletion test/Syntax/round_trip_parse_gen.swift
Expand Up @@ -103,12 +103,14 @@ class C {
init!(a: Int) {}
init?(a: Int) {}
public init(a: Int) throws {}
init(a: Int..., b: Double...) {}

@objc deinit {}
private deinit {}

internal subscript(x: Int) -> Int { get {} set {} }
subscript() -> Int { return 1 }
subscript(x: Int..., y y: String...) -> Int { return 1 }

var x: Int {
address { fatalError() }
Expand Down Expand Up @@ -197,7 +199,8 @@ func foo(_ _: Int,
d _: Int = true ? 2: 3,
@objc e: X = true,
f: inout Int,
g: Int...) throws -> [Int: String] {}
g: Int...,
h: Bool...) throws -> [Int: String] {}

func foo(_ a: Int) throws -> Int {}
func foo( a: Int) rethrows -> Int {}
Expand Down
33 changes: 32 additions & 1 deletion test/decl/func/vararg.swift
Expand Up @@ -27,7 +27,38 @@ func invalidVariadic(_ e: NonExistentType) { // expected-error {{cannot find typ
{ (e: ExtraCrispy...) in }() // expected-error {{cannot find type 'ExtraCrispy' in scope}}
}

func twoVariadics(_ a: Int..., b: Int...) { } // expected-error{{only a single variadic parameter '...' is permitted}} {{38-41=}}
func twoVariadics(_ a: Int..., b: Int...) { }
func unlabeledFollowingVariadic(_ a: Int..., _ b: Int) { } // expected-error {{a parameter following a variadic parameter requires a label}}
func unlabeledVariadicFollowingVariadic(_ a: Int..., _ b: Int...) { } // expected-error {{a parameter following a variadic parameter requires a label}}
func unlabeledFollowingTwoVariadics(_ a: Int..., b: Int..., _ c: Int) { } // expected-error {{a parameter following a variadic parameter requires a label}}
func splitVariadics(_ a: Int..., b: Int, _ c: String...) { }
func splitByDefaultArgVariadics(_ a: Int..., b: Int = 0, _ c: String...) { }

struct HasSubscripts {
subscript(a: Int...) -> Void { () }
subscript(a: Int..., b b: Int...) -> Void { () }
subscript(a: Int..., b: Int...) -> Void { () } // expected-error {{a parameter following a variadic parameter requires a label}}
subscript(a: Int..., b: Int) -> Void { () } // expected-error {{a parameter following a variadic parameter requires a label}}
subscript(a: Int..., b b: Int..., c c: Int) -> Void { () }
subscript(a: Int..., b b: Int..., c: Int) -> Void { () } // expected-error {{a parameter following a variadic parameter requires a label}}
subscript(a: Int..., c c: Int = 0, b: Int...) -> Void { () }
subscript(a: Int..., b: String = "hello, world!") -> Bool { false } // expected-error {{a parameter following a variadic parameter requires a label}}
}

struct HasInitializers {
init(a: Int...) {}
init(a: Int..., b: Int...) {}
init(a: Int..., _ b: Int...) {} // expected-error {{a parameter following a variadic parameter requires a label}}
init(a: Int..., c: Int = 0, _ b: Int...) {}
}

let closure = {(x: Int..., y: Int...) in } // expected-error {{no parameters may follow a variadic parameter in a closure}}
let closure2 = {(x: Int..., y: Int) in } // expected-error {{no parameters may follow a variadic parameter in a closure}}
let closure3 = {(x: Int..., y: Int, z: Int...) in } // expected-error {{no parameters may follow a variadic parameter in a closure}}
let closure4 = {(x: Int...) in }
let closure5 = {(x: Int, y: Int...) in }
let closure6 = {(x: Int..., y z: Int) in } // expected-error {{closure cannot have keyword arguments}}
// expected-error@-1 {{no parameters may follow a variadic parameter in a closure}}

// rdar://22056861
func f5(_ list: Any..., end: String = "") {}
Expand Down

0 comments on commit c6a266e

Please sign in to comment.