[swift-evolution] Warn about unused Optional.some(())

Haravikk swift-evolution at haravikk.me
Sat Feb 4 11:47:48 CST 2017

Apologies for re-posting this, but I got some message undelivered e-mails for it so I'm not 100% sure if it went through the first time or not:

> On 31 Jan 2017, at 09:07, Alex Hoppen via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> This was a deliberate change between Swift 3 beta 1 and beta 2 after a friend of mine pointed the following inconsistency out to me:
> struct Foo {
>  func bar() {}
> }
> let foo: Foo? = Foo()
> foo?.bar() // Does not create a warning
> true ? foo?.bar() : foo?.bar()  // expression of type '()?' is unused
> After some offline discussion at WWDC with the Swift team we decided to move to a consistent model where ()?, ()??, … is always discardable since we didn't want to take the convenience of foo?.bar() away (something that regularly occurs with weak variables, e.g. captures in closures).
> So much for the history of this feature.

Thanks for clarifying, but this is an interesting case actually; it seems the problem here is the ternary, as presumably the following would have worked just fine:

if true { foo?.bar() }
else { foo?.bar() }

So your example's problem seems to stem then from the fact that the ternary's type isn't inheriting the discardable nature of the two branches. I wonder then if an alternative solution might to have discardable be an inheritable property, while keeping optional chaining implicitly discardable?

For example:

@discardableResult func foo() -> Int { return 1 }
func bar() -> Int { return 2 }
struct Baz { func baz() {}}

let a:Baz? = Baz()
true ? foo() : bar() // type is Int, should produce a warning
true ? foo() : foo() // type is discardable Int, no warning necessary
true ? a?.baz() : a?.baz() // type is discardable Void, no warning necessary
The idea basically being that @discardableResult becomes a property of return types that is passed for as long as it is in common, but does not prevent two types (one discardable, one not) from being equal.

This might give a best of both? As method chaining producing implicitly discardable results would allow your example to behave as expected, but other cases can still be configured as desired with @discardableResult (or not).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170204/51160ddd/attachment.html>

More information about the swift-evolution mailing list