Swift and GCC_WARN_UNUSED_PARAMETER

Hi,

My understanding is that Objective-C can support warnings for unused function parameters, but swift doesn’t support it. I wonder how much coding would it require to implement support for it in swift? Which parts of the compiler?

(As an aside, I really like Visual Studio Code’s syntax coloring, all unused stuff is grayed out... but that’s Xcode stuff, so not a topic here)

2 Likes

Swift warns on unused local variables but not function parameters. I use SwiftLint to catch those, along with other unused cases like closure captures.

1 Like

This is SR-2849, but no one's gotten around to it yet.

2 Likes

It would have to be toggleable, otherwise Apple's delegate APIs would become unbearable. That's the main reason I don't have it turned on for Objective-C.

You would be able to explicitly ignore arguments in Swift by naming the argument binding _, e.g.:

func tableView(_ tableView: XYTableView, didDoStuffTo _: Thing) {
  doStuffWith(tableView)
  // the second argument is ignored
}
1 Like

Right, and we could mark them unused in C, but that’s dozens, if not hundreds of occurrences in an app. Hugely irritating for little benefit.

I don't think naming unused parameters _ is that annoying, it's less typing than actually giving the parameter an internal name, and most of the delegate APIs would be using an internal name. Marking the parameters in C would definitely get tiresome though.

2 Likes

I am bumping this thread because I have an implementation: https://github.com/apple/swift/pull/28839. It is supposed to be disabled by default and can be enabled by passing a flag.

It's pretty straightforward, here are a few examples to demonstrate how the warnings would work:

func foo(x: Int) { // warning + fix-it to replace 'x' with '_' OR insert '_' after 'x'
  print("I didn't use x!")
}

func bar(_ y: Int) { // warning + fix-it remove 'y'
  print("I didn't use y!")
}

func baz(x y: Int) { // warning + fix-it to replace entire parameter with '_' OR replace 'y' with '_'
  print("I didn't use y!")
}

However, there are some concerns and so I would like to gather people's thoughts and opinions on:

  1. Whether we should offer this warning at all (either unconditionally or by passing a flag)
  2. In what scenarios should the warnings be generated and what kind of fix-it should we offer
2 Likes

I would like to gather people's thoughts and opinions

Un‐naming the argument with _ would interfere with the Parameters documentation callout, since the names need to match. Having such a warning would currently make it impossible to satisfy both the compiler and swift-format’s linter at the same time.

I think it would be better (if it is possible) to check whether the method satisfies a conformance requirement or is an override. If yes, the unused parameter should be there. If no, warn with a fix‐it that removes the entire parameter.

I generally dislike this warning, and it’s largely incompatible with Apple’s APIs anyway. Every delegate method with any unused parameter would require changes after the autocomplete to silence the warning. No thank you. Since there’s no affect on the generated code, this should be a longer option (and already is).

3 Likes

I like how @beccadax put it in the PR:

Swift typically only includes warnings that we believe are so likely to be correct and helpful that we feel confident enabling them unconditionally.

If it can meet that bar, it gets my vote. Until then it doesn’t.

2 Likes

but not function parameters. I use SwiftLint to catch those

I don't see a SwiftLint rule for catching unused function parameters, do you have a custom rule for this that is not merged upstream?

I’m not sure what I was referencing there, but I don’t catch function parameters, just closure parameters. No custom rule.

I'll note the other way to silence this warning, which would be "assign to _ at the top of the method". That might be better in the long run because you still want to be able to write doc comments for your unused parameters if they might not be unused in the future.

This doesn't address the larger question of whether it's worth introducing this as an off-by-default warning (of which we have very few and I'm minorly against putting in the language), or as an always-on warning (when people might find it noisy, as noted, especially during the transition period), or not at all (because neither of this options are good enough).

1 Like

Right, or have a func unused(Any) global method that's empty.
Or have something analogous to @discardableResult to be used at the function declaration point like @ignorable.

Most parameters in callbacks or overrides are likely to be ignorable.