Tuesday, February 20, 2018

When Swift Makes You Use “throws” Instead of “rethrows”

Brent Royal-Gordon:

rethrows lets you specify that a function can only throw if one of the functions passed to it as a parameter can throw. It enforces this by only allowing try to be applied to calls to those functions or rethrows functions which are being passed those functions, and only allowing throws inside a catch block.

However, this enforcement can sometimes get in the way. For example, this function only throws if the function it is passed throws, but the compiler cannot statically prove this to itself[…]

[…]

It is possible to work around this by exploiting certain bugs in the rethrows checking—the Dispatch overlay does this to add error handling to DispatchQueue.sync(execute:)—but this is not ideal for obvious reasons.

Via Ole Begemann:

We can use the same trick for our problem. Check out the relevant code in the Swift repository. And here’s the verbatim copy of the code (I only changed the function names) for performAndWait[…]

[…]

performAndWait now calls through to a private helper function that takes two throwing functions (the original block and an error handler) and this convinces the compiler that the rethrows invariant holds.

1 Comment RSS · Twitter

[…] in many more places than before. It’s still not allowed as a parameter type, though. I have a case where I want to ensure that a method has a parameter of the receiver’s own type. I […]

Leave a Comment