Skip to content

[Parse] Error if closure has an unnamed parameter #70065

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions include/swift/AST/DiagnosticsParse.def
Original file line number Diff line number Diff line change
Expand Up @@ -1029,8 +1029,6 @@ ERROR(parameter_operator_keyword_argument,none,

ERROR(parameter_unnamed,none,
"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,
"cannot have more than one parameter list", ())
Expand Down
23 changes: 3 additions & 20 deletions lib/Parse/ParsePattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,26 +404,9 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
// Mark current parameter type as invalid so it is possible
// to diagnose it as destructuring of the closure parameter list.
param.isPotentiallyDestructured = true;
if (!isClosure) {
// Unnamed parameters must be written as "_: Type".
diagnose(typeStartLoc, diag::parameter_unnamed)
.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, "_: ");
}
}
// Unnamed parameters must be written as "_: Type".
diagnose(typeStartLoc, diag::parameter_unnamed)
.fixItInsert(typeStartLoc, "_: ");
}
} else {
// Otherwise, we're not sure what is going on, but this doesn't smell
Expand Down
2 changes: 1 addition & 1 deletion test/Constraints/closures.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,7 @@ func rdar_59741308() {
func r60074136() {
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 '_'}}
}
}

Expand Down
8 changes: 4 additions & 4 deletions test/Constraints/tuple_arguments.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1490,7 +1490,7 @@ do {
let tuple = (1, (2, 3))
[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-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@-4 {{cannot find 'z' in scope; did you mean 'x'?}}
}
Expand All @@ -1501,7 +1501,7 @@ r31892961_1.forEach { (k, v) in print(k + v) }

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-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
val + 1
// expected-error@-1 {{cannot find 'val' in scope}}
Expand All @@ -1518,13 +1518,13 @@ _ = [r31892961_4].map { x, y in x + y }
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}}
// 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'?}}

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}}
// 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'?}}

// rdar://problem/32214649 -- these regressed in Swift 4 mode
Expand Down
4 changes: 2 additions & 2 deletions test/decl/func/functions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ func bogusDestructuring() {
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 { ([String: 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-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 '_'}}

}