Swift handles this through the equivalent of Rust's `dyn`. We could have a stable ABI that's based entirely on `dyn`. Such an ABI would have some limitations, since there are traits `dyn` can't represent (anything that's generic over something other than the type that implements the trait, which is quite common), though we're working on some of those.
Essentially, you wouldn't be able to have a `Vec<T>` in your ABI without either pinning down T or using something like `Vec<Box<dyn Trait>>`. Which is possible, but kind of awful.
We're still planning to ship a stable ABI at some point, but that gives a flavor for some of the kinds of problems we'd need to solve in order for that stable ABI to be useful.
(C++ typically handles generics by having types defined in header files, and those get compiled with the program consuming the library, which is effectively the same situation Rust is in. You could export symbols from a shared library for specific instantiation of a template, but people rarely do that.)
Similar to :
#[rust_abi]
struct MustConform
fn must_conform
So the user must write the shims instead of rust magically build it. This also mean that ABI changes become visible, and changes to rust not mean worries about ABI.Forgive the naive question on something that's probably been discussed many times over, but could there be a middle ground when it comes to a stable ABI and generics? Something where the person building the library for dynamic linking chooses which explicit monomorphizations they'd like to provide for each public generic function (and type), and the compiler stamps out all combinations of those concrete instances? Could the way these are named and stamped out be standardized so that this could be treated as a stable ABI for non-generics?
It seems to me that it would at least cover distros: they could make a pass over all their Rust code and determine which monomorphizations are needed throughout the distro.