Swift 1.2b2: @noescape cannot be applied to locals, leading to duplication of code
| Originator: | rix.rob | ||
| Number: | rdar://19997577 | Date Originated: | 28-Feb-2015 06:34 PM |
| Status: | Open | Resolved: | |
| Product: | Developer Tools | Product Version: | Xcode-beta (6D532l) |
| Classification: | Other Bug | Reproducible: | Always |
Summary:
Since @noescape can’t be applied to locals, you can’t write a convenience closure which wraps a @noescape parameter and which trivially never escapes, so you have to duplicate the closure, which increases the surface area for defects.
Steps to Reproduce:
1. Write this code:
enum Type {
case Unit
case Function(() -> Type, () -> Type)
case Sum(() -> Type, () -> Type)
func reduce<Result>(initial: Result, @noescape _ combine: (Result, Type) -> Result) -> Result {
let binary: (Type, Type) -> Result = { combine(combine(combine(initial, self), $0), $1) }
switch self {
case Unit:
return combine(initial, self)
case let Function(t1, t2):
return binary(t1, t2)
case let Sum(t1, t2):
return binary(t1, t2)
}
}
}
Expected Results:
I expected it to compile. It’s pretty obvious that `combine` never escapes.
Actual Results:
It failed: `combine` is captured in a closure which may—perhaps by magic—allow it to escape.
Regression:
N/A
Notes:
I also tried @noescape let binary: (Type, Type) -> Result = … but “'noescape' may only be used on 'parameter' declarations,” which is sad-making.
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!