> doesn't have any way to say "this function should take a Writer"
AFAIK there isn't any dedicated pretty syntax, but there are plenty of solutions that aren't too painful. They all rely on the fact that you're not generating a "new" struct with each call -- comptime function calls assume that the same inputs will yield the same outputs and cache the results to enforce that behavior, so if you call Writer(foo) in two different places you get the _exact_ same struct in both places.
One option would be to instantiate the Writer type just as you would dependent generics in any other language.
fn foo(comptime writerFn: anytype, comptime WriterT: Writer(writerFn), writer: WriterT)
Another option would be to just check the type at comptime. You're able to throw custom error messages during compilation, and comptime code doesn't add runtime overhead of any sort.
fn foo(writer: anytype) !void { checkWriterT(@TypeOf(writer)) }
For completeness, it's worth noting that the correct behavior for strings and more complicated objects is still AFAIK a subject of debate with respect to comptime caching. It should have some nice solution by 1.0 in a few years, but for primitives like functions and types you should have no issues with either of the two above approaches.