There were some discussions about typed throws
:
- Typed throw functions
- [Discussion] Analysis of the design of typed throws
- [Pitch] Typed throws
and more.
With types throws, you could use generics:
struct Foo<E: any Error> {
let maybeThrowing: () throws E -> ()
init(_ maybeThrowing: () throws E -> ()) {
self.maybeThrowing = maybeThrowing
}
func bar() throws E {
try maybeThrowing()
}
}
var foo1 = Foo { print("Foo") } // Foo<Never>
foo1.bar()
let foo2 = Foo { throw Error() } // Foo<Error>
do {
try foo2.bar()
} catch {
print("Error")
}
foo1 = foo2 // error: Cannot assign value of Foo<Error> to variable of type Foo<Never>
Also note that existential type Error
(aka any Error
) does not conform to Error
. So
for the Foo<Error>
to work, we would need another feature, which is not yet implemented - Existential subtyping as generic constraint.