mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Parse] Error if closure has an unnamed parameter
We accepted unnamed closure parameters if the type was an array literal, dictionary literal, tuple or function (because the `[` or `(` starting the type was sufficient to disambiguate the type from the parameter’s name). This was never an accepted syntax and we should disallow it.
This commit is contained in:
@@ -1029,8 +1029,6 @@ ERROR(parameter_operator_keyword_argument,none,
|
|||||||
|
|
||||||
ERROR(parameter_unnamed,none,
|
ERROR(parameter_unnamed,none,
|
||||||
"unnamed parameters must be written with the empty name '_'", ())
|
"unnamed parameters must be written with the empty name '_'", ())
|
||||||
WARNING(parameter_unnamed_warn,none,
|
|
||||||
"unnamed parameters must be written with the empty name '_'", ())
|
|
||||||
|
|
||||||
ERROR(parameter_curry_syntax_removed,none,
|
ERROR(parameter_curry_syntax_removed,none,
|
||||||
"cannot have more than one parameter list", ())
|
"cannot have more than one parameter list", ())
|
||||||
|
|||||||
@@ -404,26 +404,9 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
|
|||||||
// Mark current parameter type as invalid so it is possible
|
// Mark current parameter type as invalid so it is possible
|
||||||
// to diagnose it as destructuring of the closure parameter list.
|
// to diagnose it as destructuring of the closure parameter list.
|
||||||
param.isPotentiallyDestructured = true;
|
param.isPotentiallyDestructured = true;
|
||||||
if (!isClosure) {
|
// Unnamed parameters must be written as "_: Type".
|
||||||
// Unnamed parameters must be written as "_: Type".
|
diagnose(typeStartLoc, diag::parameter_unnamed)
|
||||||
diagnose(typeStartLoc, diag::parameter_unnamed)
|
.fixItInsert(typeStartLoc, "_: ");
|
||||||
.fixItInsert(typeStartLoc, "_: ");
|
|
||||||
} else {
|
|
||||||
// Unnamed parameters were accidentally possibly accepted after
|
|
||||||
// SE-110 depending on the kind of declaration. We now need to
|
|
||||||
// warn about the misuse of this syntax and offer to
|
|
||||||
// fix it.
|
|
||||||
// An exception to this rule is when the type is declared with type sugar
|
|
||||||
// Reference: https://github.com/apple/swift/issues/54133
|
|
||||||
if (isa<OptionalTypeRepr>(param.Type)
|
|
||||||
|| isa<ImplicitlyUnwrappedOptionalTypeRepr>(param.Type)) {
|
|
||||||
diagnose(typeStartLoc, diag::parameter_unnamed)
|
|
||||||
.fixItInsert(typeStartLoc, "_: ");
|
|
||||||
} else {
|
|
||||||
diagnose(typeStartLoc, diag::parameter_unnamed_warn)
|
|
||||||
.fixItInsert(typeStartLoc, "_: ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, we're not sure what is going on, but this doesn't smell
|
// Otherwise, we're not sure what is going on, but this doesn't smell
|
||||||
|
|||||||
@@ -1026,7 +1026,7 @@ func rdar_59741308() {
|
|||||||
func r60074136() {
|
func r60074136() {
|
||||||
func takesClosure(_ closure: ((Int) -> Void) -> Void) {}
|
func takesClosure(_ closure: ((Int) -> Void) -> Void) {}
|
||||||
|
|
||||||
takesClosure { ((Int) -> Void) -> Void in // expected-warning {{unnamed parameters must be written with the empty name '_'}}
|
takesClosure { ((Int) -> Void) -> Void in // expected-error {{unnamed parameters must be written with the empty name '_'}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1490,7 +1490,7 @@ do {
|
|||||||
let tuple = (1, (2, 3))
|
let tuple = (1, (2, 3))
|
||||||
[tuple].map { (x, (y, z)) -> Int in x + y + z } // expected-note 2 {{'x' declared here}}
|
[tuple].map { (x, (y, z)) -> Int in x + y + z } // expected-note 2 {{'x' declared here}}
|
||||||
// expected-error@-1 {{closure tuple parameter does not support destructuring}} {{21-27=arg1}} {{39-39=let (y, z) = arg1; }}
|
// expected-error@-1 {{closure tuple parameter does not support destructuring}} {{21-27=arg1}} {{39-39=let (y, z) = arg1; }}
|
||||||
// expected-warning@-2 {{unnamed parameters must be written with the empty name '_'}} {{21-21=_: }}
|
// expected-error@-2 {{unnamed parameters must be written with the empty name '_'}} {{21-21=_: }}
|
||||||
// expected-error@-3 {{cannot find 'y' in scope; did you mean 'x'?}}
|
// expected-error@-3 {{cannot find 'y' in scope; did you mean 'x'?}}
|
||||||
// expected-error@-4 {{cannot find 'z' in scope; did you mean 'x'?}}
|
// expected-error@-4 {{cannot find 'z' in scope; did you mean 'x'?}}
|
||||||
}
|
}
|
||||||
@@ -1501,7 +1501,7 @@ r31892961_1.forEach { (k, v) in print(k + v) }
|
|||||||
|
|
||||||
let r31892961_2 = [1, 2, 3]
|
let r31892961_2 = [1, 2, 3]
|
||||||
// expected-error@+2 {{closure tuple parameter does not support destructuring}} {{48-60=arg0}} {{+1:3-3=\n let (index, val) = arg0\n }}
|
// expected-error@+2 {{closure tuple parameter does not support destructuring}} {{48-60=arg0}} {{+1:3-3=\n let (index, val) = arg0\n }}
|
||||||
// expected-warning@+1 {{unnamed parameters must be written with the empty name '_'}} {{48-48=_: }}
|
// expected-error@+1 {{unnamed parameters must be written with the empty name '_'}} {{48-48=_: }}
|
||||||
let _: [Int] = r31892961_2.enumerated().map { ((index, val)) in
|
let _: [Int] = r31892961_2.enumerated().map { ((index, val)) in
|
||||||
val + 1
|
val + 1
|
||||||
// expected-error@-1 {{cannot find 'val' in scope}}
|
// expected-error@-1 {{cannot find 'val' in scope}}
|
||||||
@@ -1518,13 +1518,13 @@ _ = [r31892961_4].map { x, y in x + y }
|
|||||||
let r31892961_5 = (x: 1, (y: 2, (w: 3, z: 4)))
|
let r31892961_5 = (x: 1, (y: 2, (w: 3, z: 4)))
|
||||||
[r31892961_5].map { (x: Int, (y: Int, (w: Int, z: Int))) in x + y } // expected-note {{'x' declared here}}
|
[r31892961_5].map { (x: Int, (y: Int, (w: Int, z: Int))) in x + y } // expected-note {{'x' declared here}}
|
||||||
// expected-error@-1 {{closure tuple parameter does not support destructuring}} {{30-56=arg1}} {{61-61=let (y, (w, z)) = arg1; }}
|
// expected-error@-1 {{closure tuple parameter does not support destructuring}} {{30-56=arg1}} {{61-61=let (y, (w, z)) = arg1; }}
|
||||||
// expected-warning@-2 {{unnamed parameters must be written with the empty name '_'}} {{30-30=_: }}
|
// expected-error@-2 {{unnamed parameters must be written with the empty name '_'}} {{30-30=_: }}
|
||||||
// expected-error@-3{{cannot find 'y' in scope; did you mean 'x'?}}
|
// expected-error@-3{{cannot find 'y' in scope; did you mean 'x'?}}
|
||||||
|
|
||||||
let r31892961_6 = (x: 1, (y: 2, z: 4))
|
let r31892961_6 = (x: 1, (y: 2, z: 4))
|
||||||
[r31892961_6].map { (x: Int, (y: Int, z: Int)) in x + y } // expected-note {{'x' declared here}}
|
[r31892961_6].map { (x: Int, (y: Int, z: Int)) in x + y } // expected-note {{'x' declared here}}
|
||||||
// expected-error@-1 {{closure tuple parameter does not support destructuring}} {{30-46=arg1}} {{51-51=let (y, z) = arg1; }}
|
// expected-error@-1 {{closure tuple parameter does not support destructuring}} {{30-46=arg1}} {{51-51=let (y, z) = arg1; }}
|
||||||
// expected-warning@-2 {{unnamed parameters must be written with the empty name '_'}} {{30-30=_: }}
|
// expected-error@-2 {{unnamed parameters must be written with the empty name '_'}} {{30-30=_: }}
|
||||||
// expected-error@-3{{cannot find 'y' in scope; did you mean 'x'?}}
|
// expected-error@-3{{cannot find 'y' in scope; did you mean 'x'?}}
|
||||||
|
|
||||||
// rdar://problem/32214649 -- these regressed in Swift 4 mode
|
// rdar://problem/32214649 -- these regressed in Swift 4 mode
|
||||||
|
|||||||
@@ -192,8 +192,8 @@ func bogusDestructuring() {
|
|||||||
func registerCallback(_ callback: @escaping (Bar?) -> Void) {}
|
func registerCallback(_ callback: @escaping (Bar?) -> Void) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Foo().registerCallback { ([Bar]) in } // expected-warning {{unnamed parameters must be written with the empty name '_'}} {{29-29=_: }}
|
Foo().registerCallback { ([Bar]) in } // expected-error {{unnamed parameters must be written with the empty name '_'}} {{29-29=_: }}
|
||||||
Foo().registerCallback { ([String: Bar]) in }// expected-warning {{unnamed parameters must be written with the empty name '_'}} {{29-29=_: }}
|
Foo().registerCallback { ([String: Bar]) in }// expected-error {{unnamed parameters must be written with the empty name '_'}} {{29-29=_: }}
|
||||||
Foo().registerCallback { (Bar?) in } // expected-error {{unnamed parameters must be written with the empty name '_'}}
|
Foo().registerCallback { (Bar?) in } // expected-error {{unnamed parameters must be written with the empty name '_'}}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user