<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Sep 7, 2016, at 6:50 PM, Jacob Bandes-Storch &lt;<a href="mailto:jtbandes@gmail.com" class="">jtbandes@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class=""><div class="gmail_signature"><div dir="ltr" class=""><div class="">On Wed, Sep 7, 2016 at 5:54 PM, Michael Ilseman via swift-users <span dir="ltr" class="">&lt;<a href="mailto:swift-users@swift.org" target="_blank" class="">swift-users@swift.org</a>&gt;</span> wrote:<br class=""></div></div></div></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class="">I implemented a better (i.e. correct) diagnostic message for this at&nbsp;<a href="https://github.com/apple/swift/pull/4670" target="_blank" class="">https://github.com/apple/<wbr class="">swift/pull/4670</a>. I want to also do a better diagnostic specifically for aggregate parameters to functions (e.g. optional closures), but that requires more work in the type checker.</div><div class=""><br class=""></div><div class="">Basically, @escaping is valid only on closures in function parameter position. The noescape-by-default rule only applies to these closures at function parameter position, otherwise they are escaping. Aggregates, such as enums with associated values (e.g. Optional), tuples, structs, etc., if they have closures, follow the default rules for closures that are not at function parameter position, i.e. they are escaping.</div></div></blockquote><div class=""><br class=""></div><div class="">Shouldn't it be possible to allow distinguishing @escaping/@noescape for aggregates like these, at least for the simple case of Optional? &nbsp;(I handled optionals in&nbsp;<a href="https://github.com/apple/swift/pull/4438" class="">https://github.com/apple/swift/pull/4438</a> for imported function types; see <a href="https://github.com/apple/swift/pull/4438#issuecomment-243645367" class="">comment</a>.)</div><div class="">&nbsp;</div></div></div></div></div></blockquote><div><br class=""></div><div>Yes it is possible (but *not* in time for Swift 3) to address this. Optional at the very least would be the highest bang for our buck, along with other single-type aggregate structures. A general solution would require some kind of aggregate liveness solution, but we can get something very good with a bit less: we could express such things with the ‘@escaping’ still being at the immediate function parameter position, and applying it throughout aggregate types in a principled fashion. E.g.:</div><div><br class=""></div><div>func foo(_ a: @escaping ((Int) -&gt; Int)?) {}</div><div><div>func foo(_ a: @escaping (Int, (Int) -&gt; Int)) {}</div><div><div>func foo(_ a: @escaping ((Int) -&gt; Int, (Int) -&gt; Int)) {} // both are escaping</div><div class=""></div></div><div class=""><div>func foo(_ a: @escaping [(Int) -&gt; Int]? {} // they are all escaping</div></div><div class=""><br class=""></div><div class="">Struct aggregate members and protocol associated types would not be impacted by this, as their member types are not listed in their signature, only tuples and generic type parameters (modulo sugar).</div><div class=""><br class=""></div><div class="">This would re-enforce that it’s about the parameter position specifically being a special case. Also, I don’t think there’s any practical benefit to finer grained escapability, e.g. some tuple elements are escaping and some are not. Though, at this point, maybe it makes more sense being a parameter attribute, rather than a type attribute…</div><div class=""><br class=""></div><div class="">Any solution should be discussed further on swift-evolution.</div><div class=""><br class=""></div></div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><div class=""><br class=""></div><div class="">It would be a post-Swift-3 addition to the language to be able to support more robust liveness tracking here. There may be interesting directions to take this, with optional closures being the most common beneficiary.&nbsp;</div><div class=""><div class="gmail-h5"><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class="">On Sep 7, 2016, at 3:33 PM, Shawn Erickson via swift-users &lt;<a href="mailto:swift-users@swift.org" target="_blank" class="">swift-users@swift.org</a>&gt; wrote:</div><br class=""><div class=""><div dir="ltr" class="">I see&nbsp;<a href="https://bugs.swift.org/browse/SR-2324" target="_blank" class="">https://bugs.swift.org/<wbr class="">browse/SR-2324</a>&nbsp;and <a href="https://bugs.swift.org/browse/SR-2444" target="_blank" class="">https://bugs.swift.org/browse/<wbr class="">SR-2444</a>&nbsp;which looks related to this issue and may explain the error I saw on "the other side" of this.<div class=""><br class=""></div><div class=""><br class=""></div></div><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Wed, Sep 7, 2016 at 3:28 PM Shawn Erickson &lt;<a href="mailto:shawnce@gmail.com" target="_blank" class="">shawnce@gmail.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class="">Yeah I actually have a few of those myself that I can no longer do.</div><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Wed, Sep 7, 2016 at 3:26 PM Jon Shier &lt;<a href="mailto:jon@jonshier.com" target="_blank" class="">jon@jonshier.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class="">Perhaps relatedly, it no longer seems possible to mark typealiased closures as @escaping. That was quite handy when you know that closures will always be used asynchronously.<div class=""><br class=""></div><div class=""><br class=""></div><div class="">Jon</div><div class=""><br class=""></div><div class=""><br class=""><div class=""><blockquote type="cite" class=""></blockquote></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class=""><blockquote type="cite" class=""><div class="">On Sep 7, 2016, at 6:15 PM, Shawn Erickson via swift-users &lt;<a href="mailto:swift-users@swift.org" target="_blank" class="">swift-users@swift.org</a>&gt; wrote:</div><br class=""></blockquote></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="">I should note that this issue also appeared in an earlier variant of Swift after the addition of @escaping but I was on vacation so didn't get a chance to report it then. It isn't new with the Xcode 8 GM.<br class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Wed, Sep 7, 2016 at 3:08 PM Shawn Erickson &lt;<a href="mailto:shawnce@gmail.com" target="_blank" class="">shawnce@gmail.com</a>&gt; wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr" class="">I like and fully supported the change to @escaping away from @noescape however in a body of code that I am porting to the latest Swift 3 variant (as found in Xcode 8 GM) I am hitting an issue for methods that take an optional completion closure. If optional is involved I can't find a way to apply @escape to the escaping closure. See the following for an basic example...<div class=""><br class=""></div><div class="">Is their a way to do what I need and/or is this an edge case in the implementation of @escaping?<br class=""><div class=""><br class=""></div><div class=""><div class=""><font face="monospace" size="1" class="">typealias MyCallback = (String)-&gt;()</font></div><div class=""><font face="monospace" size="1" class=""><br class=""></font></div><div class=""><font face="monospace" size="1" class="">// Happy</font></div><div class=""><font face="monospace" size="1" class="">func foo1(bar: String, completion: ((String)-&gt;())) {</font></div><div class=""><font face="monospace" size="1" class="">&nbsp; &nbsp; completion(bar)</font></div><div class=""><font face="monospace" size="1" class="">}</font></div><div class=""><font face="monospace" size="1" class=""><br class=""></font></div><div class=""><font face="monospace" size="1" class="">// Happy</font></div><div class=""><font face="monospace" size="1" class="">func foo2(bar: String, completion: MyCallback) {</font></div><div class=""><font face="monospace" size="1" class="">&nbsp; &nbsp; completion(bar)</font></div><div class=""><font face="monospace" size="1" class="">}</font></div><div class=""><font face="monospace" size="1" class=""><br class=""></font></div><div class=""><font face="monospace" size="1" class="">// Happy</font></div><div class=""><font face="monospace" size="1" class="">func foo3(bar: String, completion: ((String)-&gt;())? = nil) {</font></div><div class=""><font face="monospace" size="1" class="">&nbsp; &nbsp; completion?(bar)</font></div><div class=""><font face="monospace" size="1" class="">}</font></div><div class=""><font face="monospace" size="1" class=""><br class=""></font></div><div class=""><font face="monospace" size="1" class="">// Happy</font></div><div class=""><font face="monospace" size="1" class="">func foo4(bar: String, completion: MyCallback? = nil) {</font></div><div class=""><font face="monospace" size="1" class="">&nbsp; &nbsp; completion?(bar)</font></div><div class=""><font face="monospace" size="1" class="">}</font></div><div class=""><font face="monospace" size="1" class=""><br class=""></font></div><div class=""><font face="monospace" size="1" class="">// Happy</font></div><div class=""><font face="monospace" size="1" class="">func foo5(bar: String, completion: Optional&lt;MyCallback&gt; = nil) {</font></div><div class=""><font face="monospace" size="1" class="">&nbsp; &nbsp; completion?(bar)</font></div><div class=""><font face="monospace" size="1" class="">}</font></div><div class=""><font face="monospace" size="1" class=""><br class=""></font></div><div class=""><font face="monospace" size="1" class="">// Happy</font></div><div class=""><font face="monospace" size="1" class="">func foo6(bar: String, completion: @escaping (String)-&gt;()) {</font></div><div class=""><font face="monospace" size="1" class="">&nbsp; &nbsp; completion(bar)</font></div><div class=""><font face="monospace" size="1" class="">}</font></div><div class=""><font face="monospace" size="1" class=""><br class=""></font></div><div class=""><font face="monospace" size="1" class="">// Happy</font></div><div class=""><font face="monospace" size="1" class="">func foo7(bar: String, completion: @escaping MyCallback) {</font></div><div class=""><font face="monospace" size="1" class="">&nbsp; &nbsp; completion(bar)</font></div><div class=""><font face="monospace" size="1" class="">}</font></div><div class=""><font face="monospace" size="1" class=""><br class=""></font></div><div class=""><font face="monospace" size="1" class="">// Unhappy...</font></div><div class=""><font face="monospace" size="1" class="">// "@escaping attribute only applies to function types"</font></div><div class=""><font face="monospace" size="1" class="">func foo8(bar: String, completion: @escaping ((String)-&gt;())? = nil) {</font></div><div class=""><font face="monospace" size="1" class="">&nbsp; &nbsp; completion?(bar)</font></div><div class=""><font face="monospace" size="1" class="">}</font></div><div class=""><font face="monospace" size="1" class=""><br class=""></font></div><div class=""><font face="monospace" size="1" class="">// Unhappy...</font></div><div class=""><font face="monospace" size="1" class="">// "@escaping attribute only applies to function types"</font></div><div class=""><font face="monospace" size="1" class="">func foo9(bar: String, completion: @escaping MyCallback? = nil) {</font></div><div class=""><font face="monospace" size="1" class="">&nbsp; &nbsp; completion?(bar)</font></div><div class=""><font face="monospace" size="1" class="">}</font></div><div class=""><font face="monospace" size="1" class=""><br class=""></font></div><div class=""><font face="monospace" size="1" class="">// Unhappy...</font></div><div class=""><font face="monospace" size="1" class="">// "@escaping attribute only applies to function types"</font></div><div class=""><font face="monospace" size="1" class="">func foo10(bar: String, completion: (@escaping ((String)-&gt;()))? = nil) {</font></div><div class=""><font face="monospace" size="1" class="">&nbsp; &nbsp; completion?(bar)</font></div><div class=""><font face="monospace" size="1" class="">}</font></div><div class=""><font face="monospace" size="1" class=""><br class=""></font></div><div class=""><font face="monospace" size="1" class="">// Unhappy...</font></div><div class=""><font face="monospace" size="1" class="">// "@escaping attribute only applies to function types"</font></div><div class=""><font face="monospace" size="1" class="">func foo11(bar: String, completion: (@escaping MyCallback)? = nil) {</font></div><div class=""><font face="monospace" size="1" class="">&nbsp; &nbsp; completion?(bar)</font></div><div class=""><font face="monospace" size="1" class="">}</font></div><div class=""><font face="monospace" size="1" class=""><br class=""></font></div><div class=""><font face="monospace" size="1" class="">// Unhappy...</font></div><div class=""><font face="monospace" size="1" class="">// "@escaping attribute only applies to function types"</font></div><div class=""><font face="monospace" size="1" class="">func foo12(bar: String, completion: Optional&lt;@escaping MyCallback&gt; = nil) {</font></div><div class=""><font face="monospace" size="1" class="">&nbsp; &nbsp; completion?(bar)</font></div><div class=""><font face="monospace" size="1" class="">}</font></div></div></div></div></blockquote></div></div></div></blockquote></div></div></div><div style="word-wrap:break-word" class=""><div class=""><div class=""><blockquote type="cite" class=""><div class="">
______________________________<wbr class="">_________________<br class="">swift-users mailing list<br class=""><a href="mailto:swift-users@swift.org" target="_blank" class="">swift-users@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-users" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-users</a><br class=""></div></blockquote></div><br class=""></div></div></blockquote></div></blockquote></div>
______________________________<wbr class="">_________________<br class="">swift-users mailing list<br class=""><a href="mailto:swift-users@swift.org" target="_blank" class="">swift-users@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-users" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-users</a><br class=""></div></blockquote></div><br class=""></div></div></div><br class="">______________________________<wbr class="">_________________<br class="">
swift-users mailing list<br class="">
<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-users" rel="noreferrer" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-users</a><br class="">
<br class=""></blockquote></div><br class=""></div></div>
</div></blockquote></div><br class=""></body></html>