I've written a lot of structs that have "maybe borrowed" contents. I usually reach for std::borrow::Cow for this. It's not exactly the same: we need to branch at runtime instead of having multiple generated codepaths.
I agree that in this case I can move to branch at runtime (the runtime cost is irrelevant for my use case), I still feel that it illustrates how it complicates deriving a universal type id.
The more general issue is that removing generic requires the lib to pick the implementation and remove choice from the consumer. Sometimes it's not that important, sometimes it matters more. Another example I have in my project is that I have a trait describing a `User` (with e.g. `get_name`) it may be implemented as a `LinuxUser` or `WindowsUser`, each providing extra fields. How do you generate a universal id for a struct generic over a `User`?