-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Description
Motivation
Consider the code
func f() { doSomething() }
let h = { () in f() }
Clearly, h
is of type () -> ()
.
But you might want to call the following function g
instead of f
in h
, because g
does something more appropriate:
@discardableResult
func g() -> Int { doSomethingElse(); return 1 }
let h = { () in g() }
Now the type of h
is () -> Int
, but this might come unexpected, because you use g
at other places while ignoring its result. Also, even if you are aware that g
has a discardable result, the type of h
is now intuitively unclear.
Proposed solution
If a discardable result determines the type of a closure as described in the example in the motivation part, there should be a warning. A warning should not hurt existing code bases too much, as code then still compiles if it compiled before. In the example above, you can add “return ” or “_ = “ to silence that warning:
let h = { () in return g() } // h: () -> Int
or
let h = { () in _ = g() } // h: () -> ()
A warning is not necessary in the following cases:
let h = { () in if myCondition { 2 } else { g() } } // h: () -> Int
and
let h = { () in if myCondition { print("not calling g") } else { g() } } // h: () -> ()
There are cases where type annotations (and to make them possible maybe some further refactoring, or some refactoring alone without added type annotations) are then necessary to silence the warning:
With another function with a discardable result
@discardableResult
func g2() -> Int { doSomethingElse(); return 2 }
you would have to write
let h: () -> Int = { () in if myCondition { g2() } else { g() } }
or
let h: () -> () = { () in if myCondition { g2() } else { g() } }
Alternatives considered
The alternative is to leave it as it is (no warning).
Additional information
The issue came up in the discussion of the Swift forums topic Last expression as return value. The pitch discussed there would be source breaking in a case that would get the warning proposed here.