[swift-users] Swift 3 (Xcode 8 GM) issue with @escaping

Shawn Erickson shawnce at gmail.com
Wed Sep 7 22:06:46 CDT 2016


To more completely state what I find it a little strange.

The default was moved to be non-escaping since that is the better default
(for various reason) with @escaping being used to both inform the compiler
that something is intentionally escaping (yeah I meant to do that) and to
me it seem also helpful as a way to inform the user of the API that the
closure they are providing is escaping so they better understand the
requirements placed on that closure (e.g. it may not be called before the
called function returns, possible retain cycle issues, etc.).

So when using APIs I would look for @escaping as a way to know I need to
think a little more about the behavior of the closure and the func taking
the closure that I am calling. If I don't see it I may incorrectly assume
it isn't escaping when intact it may have be implicitly escaping.

Anyway my thoughts on this...

-Shawn



On Wed, Sep 7, 2016 at 7:08 PM Shawn Erickson <shawnce at gmail.com> wrote:

> It just seems a little strange that @escaping only shows up once in the
> following example (real) function of mine yet both of them are escaping.
> This fixit message should maybe imply that @escaping isn't needed since the
> optional one is already implicitly considered escaping? ...it is kinda
> confusing when first jumping over to Swift if at one point you are told you
> need to added @escaping (the non-optional one) yet you are told @escaping
> isn't valid for the optional one despite it needing to be escaping (e.g.
> the fixit doesn't really explain that is already escaping).
>
>     func httpGet<T>(path: String, parameters: [String:String] = [:],
>                     needsAuth: Bool = true, queue: DispatchQueue =
> DispatchQueue.main,
>                     completion: ObjectFetchCallback<T>?, importer:
> @escaping HttpImporterCallback<T>)
>
> -Shawn
>
> On Wed, Sep 7, 2016 at 6:51 PM Jacob Bandes-Storch <jtbandes at gmail.com>
> wrote:
>
>> On Wed, Sep 7, 2016 at 5:54 PM, Michael Ilseman via swift-users <
>> swift-users at swift.org> wrote:
>>
>>> I implemented a better (i.e. correct) diagnostic message for this at
>>> https://github.com/apple/swift/pull/4670. 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.
>>>
>>> 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.
>>>
>>
>> Shouldn't it be possible to allow distinguishing @escaping/@noescape for
>> aggregates like these, at least for the simple case of Optional?  (I
>> handled optionals in https://github.com/apple/swift/pull/4438 for
>> imported function types; see comment
>> <https://github.com/apple/swift/pull/4438#issuecomment-243645367>.)
>>
>>
>>>
>>> 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.
>>>
>>> On Sep 7, 2016, at 3:33 PM, Shawn Erickson via swift-users <
>>> swift-users at swift.org> wrote:
>>>
>>> I see https://bugs.swift.org/browse/SR-2324 and
>>> https://bugs.swift.org/browse/SR-2444 which looks related to this issue
>>> and may explain the error I saw on "the other side" of this.
>>>
>>>
>>>
>>> On Wed, Sep 7, 2016 at 3:28 PM Shawn Erickson <shawnce at gmail.com> wrote:
>>>
>>>> Yeah I actually have a few of those myself that I can no longer do.
>>>>
>>>> On Wed, Sep 7, 2016 at 3:26 PM Jon Shier <jon at jonshier.com> wrote:
>>>>
>>>>> 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.
>>>>>
>>>>>
>>>>> Jon
>>>>>
>>>>>
>>>>> On Sep 7, 2016, at 6:15 PM, Shawn Erickson via swift-users <
>>>>> swift-users at swift.org> wrote:
>>>>>
>>>>> 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.
>>>>>
>>>>> On Wed, Sep 7, 2016 at 3:08 PM Shawn Erickson <shawnce at gmail.com>
>>>>> wrote:
>>>>>
>>>>>> 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...
>>>>>>
>>>>>> Is their a way to do what I need and/or is this an edge case in the
>>>>>> implementation of @escaping?
>>>>>>
>>>>>> typealias MyCallback = (String)->()
>>>>>>
>>>>>> // Happy
>>>>>> func foo1(bar: String, completion: ((String)->())) {
>>>>>>     completion(bar)
>>>>>> }
>>>>>>
>>>>>> // Happy
>>>>>> func foo2(bar: String, completion: MyCallback) {
>>>>>>     completion(bar)
>>>>>> }
>>>>>>
>>>>>> // Happy
>>>>>> func foo3(bar: String, completion: ((String)->())? = nil) {
>>>>>>     completion?(bar)
>>>>>> }
>>>>>>
>>>>>> // Happy
>>>>>> func foo4(bar: String, completion: MyCallback? = nil) {
>>>>>>     completion?(bar)
>>>>>> }
>>>>>>
>>>>>> // Happy
>>>>>> func foo5(bar: String, completion: Optional<MyCallback> = nil) {
>>>>>>     completion?(bar)
>>>>>> }
>>>>>>
>>>>>> // Happy
>>>>>> func foo6(bar: String, completion: @escaping (String)->()) {
>>>>>>     completion(bar)
>>>>>> }
>>>>>>
>>>>>> // Happy
>>>>>> func foo7(bar: String, completion: @escaping MyCallback) {
>>>>>>     completion(bar)
>>>>>> }
>>>>>>
>>>>>> // Unhappy...
>>>>>> // "@escaping attribute only applies to function types"
>>>>>> func foo8(bar: String, completion: @escaping ((String)->())? = nil) {
>>>>>>     completion?(bar)
>>>>>> }
>>>>>>
>>>>>> // Unhappy...
>>>>>> // "@escaping attribute only applies to function types"
>>>>>> func foo9(bar: String, completion: @escaping MyCallback? = nil) {
>>>>>>     completion?(bar)
>>>>>> }
>>>>>>
>>>>>> // Unhappy...
>>>>>> // "@escaping attribute only applies to function types"
>>>>>> func foo10(bar: String, completion: (@escaping ((String)->()))? =
>>>>>> nil) {
>>>>>>     completion?(bar)
>>>>>> }
>>>>>>
>>>>>> // Unhappy...
>>>>>> // "@escaping attribute only applies to function types"
>>>>>> func foo11(bar: String, completion: (@escaping MyCallback)? = nil) {
>>>>>>     completion?(bar)
>>>>>> }
>>>>>>
>>>>>> // Unhappy...
>>>>>> // "@escaping attribute only applies to function types"
>>>>>> func foo12(bar: String, completion: Optional<@escaping MyCallback> =
>>>>>> nil) {
>>>>>>     completion?(bar)
>>>>>> }
>>>>>>
>>>>> _______________________________________________
>>>>> swift-users mailing list
>>>>> swift-users at swift.org
>>>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>>>
>>>>>
>>>>> _______________________________________________
>>> swift-users mailing list
>>> swift-users at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>
>>>
>>>
>>> _______________________________________________
>>> swift-users mailing list
>>> swift-users at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>
>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160908/8b635a3f/attachment.html>


More information about the swift-users mailing list