From 4ba4da45b92cce33412cb0e13fa7789c4865f31c Mon Sep 17 00:00:00 2001 From: Alex Hoppen Date: Tue, 28 Nov 2023 10:59:17 -0800 Subject: [PATCH] [Parse] Error if closure has an unnamed parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- include/swift/AST/DiagnosticsParse.def | 2 -- lib/Parse/ParsePattern.cpp | 23 +++-------------------- test/Constraints/closures.swift | 2 +- test/Constraints/tuple_arguments.swift | 8 ++++---- test/decl/func/functions.swift | 4 ++-- 5 files changed, 10 insertions(+), 29 deletions(-) diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def index a70257be826c3..95b2b5fad111d 100644 --- a/include/swift/AST/DiagnosticsParse.def +++ b/include/swift/AST/DiagnosticsParse.def @@ -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", ()) diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp index dff019dccb5dd..0fde27755a7fb 100644 --- a/lib/Parse/ParsePattern.cpp +++ b/lib/Parse/ParsePattern.cpp @@ -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(param.Type) - || isa(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 diff --git a/test/Constraints/closures.swift b/test/Constraints/closures.swift index 594291a3239db..7441d00530087 100644 --- a/test/Constraints/closures.swift +++ b/test/Constraints/closures.swift @@ -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 '_'}} } } diff --git a/test/Constraints/tuple_arguments.swift b/test/Constraints/tuple_arguments.swift index d36e6f95bed15..ad0c6acdd71a3 100644 --- a/test/Constraints/tuple_arguments.swift +++ b/test/Constraints/tuple_arguments.swift @@ -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'?}} } @@ -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}} @@ -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 diff --git a/test/decl/func/functions.swift b/test/decl/func/functions.swift index 92ffd7653b77d..a03f03d04a9a1 100644 --- a/test/decl/func/functions.swift +++ b/test/decl/func/functions.swift @@ -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 '_'}} }