How can I use a trait from a transitive dependency crate in my application?
Here's a minimal illustrative example of the problem I've run into:
In Cargo.toml, I have:
[dependencies]
mersenne_twister = "1.1.1"
rand = "0.8.5"
My crate depends on rand ^0.8.5 and mersenne_twister ^1.1.1, which itself depends on rand >=0.3, <0.5:
my-crate ---> rand 0.8.5
|
|
---> mersenne_twister 1.1.1 ----> rand >= 0.3, < 0.5
In my app, I'd like to use the implementation of trait rand::Rng for mersenne_twister::MT19937. But when I try bringing this trait into scope, it's apparently not recognized:
use mersenne_twister::MT19937;
use rand::Rng;
fn main() {
let mut rng = MT19937::new_unseeded();
let mut buffer = vec![0; 0xFFFF];
// error[E0599]: no method named `fill_bytes` found for struct `MT19937` in the current scope
rng.fill_bytes(&mut buffer);
}
My guess is that the Rng trait imported by use rand::Rng; is the one from rand 0.8.5, not the one from rand 0.4.6 that is actually implemented for MT19937, and that even though they are spelled the same way, they are distinct and unrelated traits and therefore cannot be referenced interchangeably.
So I have some questions:
Rng trait that works for MT19937 in my app? I don't think I can downgrade my dependency on rand to 0.4.6 in Cargo.toml because I need to use rand 0.8.5 elsewere in my app.mersenne_twister's API design bad practice for not re-exporting Rng?You can add multiple incompatible versions of a dependency to Cargo.toml by renaming one of them.
[dependencies]
mersenne_twister = "1.1.1"
rand = "0.8.5"
old_rand = { package = "rand", version = "0.4.6" }
But for this situation, there's already a better solution: use the MT19937 crate, which depends on the latest version of rand_core. RNG implementations should depend on rand_core instead of rand since all they need is the Rng trait and not any of the extras in rand, like distributions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With