To summarize: as of today we have two different cases of rethrows
.
1:
func foo(_ bar: () throws -> ()) rethrows {
try bar()
}
2:
func foo(_ bar: () throws -> ()) rethrows {
do {
try bar()
} catch {
throw CustomError(base: error)
}
}
Both of these should continue to work exactly as they are now, without any source code changes required.
Maybe I'm overseeing something, but I will just write my idea nonetheless.
If we had a typed throws
, we would need a typed rethrows
as well.
Our two cases, that we have today would work exactly the same, as they worked in the past. I repeat them here with the implicit types in comments.
1:
func foo(_ bar: () throws /* Error */ -> ()) rethrows /* Error */ {
try bar()
}
2:
func foo(_ bar: () throws /* Error */ -> ()) rethrows /* Error */ {
do {
try bar()
} catch {
throw CustomError(base: error)
}
}
AFAIUI, this is the pre-typed-throws
-behaviour.
Now we want the same but with typed Errors as well. So we have the following additional cases:
3 (typed version of (1)):
func foo<E>(_ bar: () throws E -> ()) rethrows E {
try bar()
}
// If every function implicitly threw Never, we could write
func foo<E>(_ bar: () throws E -> ()) throws E {
try bar()
}
// which would semantically be the same
4 (typed version of (2)):
func foo<E>(_ bar: () throws E -> ()) rethrows CustomError {
do {
try bar()
} catch {
throw CustomError(base: error)
}
}
I cannot think of a reason ATM, why this should not work.