Michael any ideas about how to deal with the following? It seems like at least a bug in the fix-it.
I assume I should open a bug on this? -Shawn On Wed, Sep 7, 2016 at 9:16 PM Shawn Erickson <shaw...@gmail.com> wrote: > I seem to have hit a possibly related @escaping issue... > > The following code worked without issue under Swift 2.x and earlier > variants of Swift 3 but after the @escaping change (fairly sure that is > what is at fault) it no longer compiles. > > protocol Foo { > // Happy > func visitValues<T>(visitors: [(key: String, body: (T) throws -> > Void)]) throws > > // Happy > func visitValues<T>(throwOnWrongType: Bool, visitors: [(key: String, > body: (T) throws -> Void)]) throws > } > > protocol FooBar { // IGNORE ME - NOT PART OF ORIGINAL CODE > // Unhappy - this is appearntly expected given prior emails in this > thread > // @escaping may only be applied to parameters of function type > func visitValues<T>(visitors: [(key: String, body: @escaping (T) > throws -> Void)]) throws > > // Unhappy - this is appearntly expected given prior emails in this > thread > // @escaping may only be applied to parameters of function type > func visitValues<T>(throwOnWrongType: Bool, visitors: [(key: String, > body: @escaping (T) throws -> Void)]) throws > } > > // Provide a default implementation for the simple visitor version > extension Foo { > // Happy > func visitValues<T>(visitors: [(String, body: (T) throws -> Void)]) > throws { > try self.visitValues(throwOnWrongType: false, visitors: visitors) > } > } > > // Unhappy > // error: type 'RealFoo' does not conform to protocol 'Foo' > struct RealFoo : Foo { > // Happy > func visitValues<T>(throwOnWrongType: Bool, visitors: [(key: String, > body: (T) throws -> Void)]) throws { > // do stuff... > } > > // error: MyPlayground.playground:23:8: error: type 'RealFoo' does not > conform to protocol 'Foo' > //struct RealFoo : Foo { > // ^ > // > // MyPlayground.playground:16:10: note: candidate has non-matching > type '<Self, T> (visitors: [(String, body: (T) throws -> Void)]) throws -> > ()' (aka '<τ_0_0, τ_1_0> (visitors: Array<(String, body: (τ_1_0) throws -> > ())>) throws -> ()') > // func visitValues<T>(visitors: [(String, body: (T) throws -> > Void)]) throws { > > // The fix-it suggestion for "error: type 'RealFoo' does not conform > to protocol 'Foo'" inserts the following which makes > // the "not conform" error go away however it doesn't compile because > of @escaping > // Unhappy > // @escaping may only be applied to parameters of function type > internal func visitValues<T>(visitors: [(key: String, body: @escaping > (T) throws -> Void)]) throws { // NOT PART OF ORIGINAL CODE > } > // The above shouldn't be needed since an implementation is provided > via an extension on protocol Foo right? > } > > On Wed, Sep 7, 2016 at 8:06 PM Shawn Erickson <shaw...@gmail.com> wrote: > >> 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 <shaw...@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 <jtban...@gmail.com> >>> wrote: >>> >>>> On Wed, Sep 7, 2016 at 5:54 PM, Michael Ilseman via swift-users < >>>> swift-users@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@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 <shaw...@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 <j...@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@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 <shaw...@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@swift.org >>>>>>> https://lists.swift.org/mailman/listinfo/swift-users >>>>>>> >>>>>>> >>>>>>> _______________________________________________ >>>>> swift-users mailing list >>>>> swift-users@swift.org >>>>> https://lists.swift.org/mailman/listinfo/swift-users >>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> swift-users mailing list >>>>> swift-users@swift.org >>>>> https://lists.swift.org/mailman/listinfo/swift-users >>>>> >>>>>
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users