Swift 3 Warning of Unused Result

I have been experimenting with converting projects to Swift 3 syntax using the migration tools in Xcode 8. This has been giving me a lot of warnings of the form “Result of call to someFunction is unused”.

By default in Swift 3 ignoring the return value of a function is now considered a warning. This post is my quick summary of what changed, how to suppress the warning if you need to and a feature which may cause you some confusion.

What Changed in Swift 3

In Swift 2.x you could tell the compiler to warn you when you ignored the return value of a function. You did that by marking the function with @warn_unused_result. For example:

@warn_unused_result func doSomething() -> Bool {
  return true
}

Calling that function without using the result will give a warning:

Result of call to 'doSomething()' is unused

You can do something similar for Objective-C code using the attribute((warn_unused_result)) annotation:

- (BOOL)doSomething __attribute__((warn_unused_result)) {
  return YES;
}

This gives the warning:

Ignoring return value of function declared with warn_unused_result attribute

Note that by default in Objective-C and Swift 2 the default is not to warn on an unused result. That changed for Swift 3. Ignoring the return value of a Swift function is now by default a warning. This explains why I am seeing a lot of new warnings when I migrate a project to Swift 3 using Xcode 8:

Xcode warnings

Silencing the Warnings - @discardableResult

There are two ways to silence the warning:

To override the default when declaring a new function and prevent a warning if you ignore the result add the @discardableResult attribute:

@discardableResult func doSomething() -> Bool {
  return true
}

Note this is now the opposite of Swift 2. We add the annotation when we want to suppress the warning.

To prevent the compiler from flooding us with warnings when importing Objective-C code the @discardableResult attribute is automatically added for all non-void functions that are not marked with the ((warn_unused_result)) attribute.

For situations where you want to suppress the warning and explicitly ignore the result of a function assign it to _:

_ = doSomething()

This looks a bit ugly to me but it does make it explicit that you are choosing to ignore the return value.

Discardable Result Lost After Optional Chaining

As I write this with Xcode 8 beta 3 there is a situation where the discardable result attribute does not work as expected. For example, popping a view controller off the navigation stack:

navigationController?.popViewController(animated: true)

The popViewController(animated: Bool) function returns us the view controller it popped from the stack. This Objective-C API is marked with @discardableResult when imported but it still gives us a warning if we do not use the return value:

Expression of type 'UIViewController?' is unused

The problem happens when we are working with an optional value. In this example we use optional chaining as the navigationController property of a view controller can be nil. Unfortunately the discardable result attribute is lost after optional chaining.

This is reported as Swift bug SR-1681. In the meantime you need to explicitly discard the result to avoid the warning:

_ = navigationController?.popViewController(animated: true)

Further Reading

Never miss a post!

iOS Size Classes Cheat Sheet

Subscribe and get my free iOS Size Classes Cheat Sheet

Success! Now check your email to confirm your subscription and download your free guide to iOS Size Classes.

There was an error submitting your subscription. Please try again.

Unsubscribe at any time.
No time to watch WWDC videos?

Sign up to get my iOS posts direct to your inbox and I will send you a free PDF of my iOS Size Classes Cheat Sheet.

OK! Check your inbox (or spam folder) for an email to confirm your details and download your free guide to iOS Size Classes.

There was an error submitting your subscription. Please try again.

Unsubscribe at any time.
Archives Categories