Depending on a common type from multiple crates


#1

I am trying to model a sort of plugin system, where data is passed around by use of typemaps (https://docs.rs/typemap/0.3.3/typemap/) between different crates. All crates use the common definition of the data type defined in an auxiliary crate, that only defines the data structures themselves to avoid being changed too often. However, I have encountered the issue that if one crate uses version A of the auxiliary crate, and another crate uses version B (even if the data structures are the same), the typemap considers there to be two different types due to the underlying TypeIds being different, breaking the pattern.

For a more concrete example, consider this:

/// crate X
pub struct MyStruct;

/// crate A
extern crate X;
use X::MyStruct;

/// crate B
extern crate X;
use X::MyStruct;

If both A and B are using the same version of crate X, then the compiler sees both MyStruct usages as identical, and typemaps work as expected. If one is using a different version (despite the definition of MyStruct being the same!) then it does not work.

The main problem here is that when using typemaps, I only get an error at run time (when the expected data cannot be found) rather than at compile time due to incompatible types. Is this a common design pattern with accepted solutions? I can think of a few ways to fix it:

  • Statically verify that the types are the same at the top level, enforcing the same crate version across dependencies
  • Encode the types with an intricate set of traits and implementations, passing in the concrete types as generic parameters to all dependencies

#2

This is a known problem that we’re working on solving with the concept of “public” dependencies that cargo would know must resolve to the same version. The relevant RFC is RFC 1977. The workaround in the meantime, afaik, is manually verifying that all your dependencies are using the exact same versions of a dependency when needed :-/