@Slava, I'm imagining that the compiler does much the same as Anton suggested, e.g. Anton's:
struct FStore<E: Error> { let f: () throws<E> -> Void init(_ f: @escaping () throws<E> -> Void) { self.f = f } func call() throws<E> { try f() } } Is much the same as my: struct FStore { let f: () throws -> Void init(_ f: @escaping () throws -> Void) { self.f = f } func call() throws { try f() } } >From a compiler point of view. The idea is that the compiler reuses some of its existing generic's infrastructure. The main differences between my proposal and Anton's is that because mine doesn't use a typed throw, E can only be 'AnyError' (any type that implements Error) or Never, and E is not explicit. The throws/rethrows distinction just becomes a compiler optimization in both cases. -- Howard. On 13 January 2017 at 10:42, Slava Pestov <spes...@apple.com> wrote: > > On Jan 11, 2017, at 2:02 PM, Howard Lovatt via swift-evolution < > swift-evolut...@swift.org> wrote: > > Another possibility, other than generics, would be to drop rethrows all > together and have the compiler infer if a throw is possible or not, > including: > > struct FStore { > let f: () throws -> Void > func call() throws { try f() } > } > > The compiler can make two versions, one if f can throw and one if it > definitely doesn't. > > > It seems that this approach is impractical, because you either have to > compile two versions of every function, or make all function bodies > available for inlining, which is a non-starter for a stable ABI. > > Slava > > > Just a thought. > > On Tue, 10 Jan 2017 at 4:29 pm, Jacob Bandes-Storch <jtban...@gmail.com> > wrote: > >> Moving to swift-users list. >> >> No, there's no way to do this today. The point of rethrows is that within >> one call site, "f(block)" can be treated as throwing if the block throws, >> or not throwing if the block doesn't throw. In your example, once the >> FStore object is constructed, the information about the original passed-in >> function is lost, so the caller has no way to know whether call() can throw >> or not. >> >> If this *were* possible, the information would somehow need to be encoded >> in the type system when creating FStore(f: block). That would require >> something like dependent typing, or generic-param-based-rethrows, e.g. >> >> struct FStore<T: () throws -> Void> { // made-up syntax >> let f: T >> func call() rethrows(T) { try f() } // throws-ness of this function >> depends on throws-ness of T >> } >> >> >> >> On Mon, Jan 9, 2017 at 9:21 PM, Howard Lovatt via swift-evolution <swift- >> evolut...@swift.org> wrote: >> >> Hi, >> >> If I have an escaping function that I store and then call, I need to >> declare the calling function as throwing, not rethrowing. EG: >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> struct FStore { >> let f: () throws -> Void >> init(f: @escaping () throws -> Void) { self.f = f } >> func call() throws { try f() } // Can't put rethrows here - have >> to use throws >> } >> Is there a better solution? >> >> Thanks for any suggestions, >> >> -- Howard. >> >> >> >> >> >> _______________________________________________ >> >> >> swift-evolution mailing list >> >> >> swift-evolut...@swift.org >> >> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> >> >> >> >> >> >> -- > -- Howard. > _______________________________________________ > swift-evolution mailing list > swift-evolut...@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution > > >
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users