Semver trick and traits, overlapping trait implementations

The semver-trick can be used to provide a limited form of compatibility with new minor/major versions of a library by re-exporting items which were unchanged or merely moved.

For traits which are not identical this is not possible, however it is possible to use a blanket implementation:

impl<T: new_crate::Trait> Trait for T { ... }

(This allows all libraries providing implementations of Trait can upgrade to the new version knowing that users of the old Trait can remain compatible, so long as they use the new patch release providing the compatibility shim.)

Unfortunately, such blanket implementations can only be used in a single direction since Rust requires that all trait implementations are unique. This restriction should be unnecessary (if, for example, such blanket trait implementations were considered weak and only used if no other implementations are available).

Should we pursue this further? This might require an extra attribute like #[weak] to be applied to such implementations, since of course other implementations may use generics. This is not the same as specialisation, which permits only limited overlap of implementations.

It turns out that in my case even a one-way blanket implementation is impossible without overlapping trait implementations of some form: rand_core 0.4→0.5 compatibility shim.

I think semver trick in the case of rand creates far more trouble than it’s worth. I would simply drop idea of compatibility shims and kept things simple. (i.e. on breaking update of rand_core publish breaking updates for crates which rely on it)

1 Like