Sounds like we’re on the same page then.
To complete my previous post, I believe all the ideas for making non-dynamically dispatched error types easier to deal with (since Box<Error> is already pretty easy if that’s what you want) fall into two categories: Generating concrete error types that can be named elsewhere, and generating anonymous error types which cannot.
I haven’t worked on any huge Rust codebases, but it seems like ergonomic generation of concrete error types is more less taken care of by macro magic libraries like error-chain. So the way to make these cases even better would be simply making macros better. And we’ve already got a pretty huge pile of macro improvements in the pipeline.
Generating anonymous error types is more interesting. The (X | Y) syntax has been frequently suggested for anonymous enums; presumably this would allow exhaustive matching in the caller despite the anonymity of the enum and its variants. The only other idea I’m aware of in this space is my “enum impl Trait” idea (see Unified Errors, a non-proliferation treaty, and extensible types) for when you don’t want/can’t have callers exhaustively matching on your error type. I believe both of these are best left until after impl Trait (at least in return position) is stable.