Suggestion: Don't allow closure parameters to shadow types

We can currently declare a closure with its parameters as just types. An exception to this rule is for sugared types where the swift compiler will throw an error,
e.g. :

  struct Bar {}
  struct Foo {
    func registerCallback(_ callback: @escaping ([Bar]) -> Void) {}
    func registerCallback(_ callback: @escaping (Bar?) -> Void) {}

// Call_1
  Foo().registerCallback { (_ : [Bar]) in } // OK
// Call_2
  Foo().registerCallback { ([Bar]) in } // expected-warning {{unnamed parameters must be written with the empty name '_'}} {{29-29=_: }}
// Call_3
  Foo().registerCallback { (_: Bar?) in } // OK
// Call_4
  Foo().registerCallback { (Bar?) in } // expected-error {{unnamed parameters must be written with the empty name '_'}}

As for the cause of a hard-failure for sugared types (Call_4), it is is because there was a bug in the parsing logic which we later on fixed it with proper diagnostics in PR#28315

As per my discussion with @codafi, closure declaration is allowed to shadow types because it's an oversight in the logic we use for parsing parameters. And that it was never the intent.

Given that we never intended this behavior in the closure declarations, how does the community feel about erroring in those situations (Call_2)? Please bear in mind this change will be source-breaking.

1 Like