Typed throw functions

Is there precedent in the language for this sort of implicit generic constraint? My mental model for generics right now is that if I supply a concrete type which satisfies the generic constraints, the call will compile. I'm wary about breaking this model. E.g., it feels wrong to me that the following compiles just fine:

func foo<T>(_: T.Type, _: () throws T -> Void) rethrows T { ... } // Compiles fine

but we would get an error here:

func bar<T>(_: T.Type) {
  foo(T.self, { }) // Error!
}

If you're limiting this only to contexts where you are inferring the throws type for a generic throws T parameter, then yes, this is source compatible (since there are no such throws T declarations today, of course).

However, if this inference is meant to be more broad, it is not source compatible:

struct Foo: Error { ... }
struct Bar: Error { ... }
var throwers = [{ throw Foo() }] // Inferred as `Array<() throws -> ()>`, or `Array<() throws Foo -> ()>`?
throwers.append({ throw Bar() }) // Compiles today, error if we infer `throws Foo`
3 Likes