I recently ran into a problem using quickcheck
, because it re-exports rand::Rng
as part of its API. However to use it, it means that any user of quickcheck
must take an explicit dependency on the same version of rand
that quickcheck
itself does. This precludes the quickcheck
user from using a different version of rand
itself. This is particularly acute because rand-0.5
has quite a few API changed from rand-0.4.
which quickcheck
currently uses
The fix for quickcheck is very straightforward, but it occurs to me that this is a general pattern. If a crate is re-exporting another crate's symbols as part of its API, it should also re-export the whole thing for use by downstream crates. This is particularly acute for crates like rand
, as rand::Rng
is just a trait, so any use of it must use the rest of the crate (or define your own Rng
instances, I guess).
@BurntSushi asked in the comments on my PR:
Do you know of any precedent with other crates that do this? For example, should every crate that derives
serde::Deserialize
(orserde::Serialize
) also re-export all ofserde
?
Which is a good question. I hadn't encountered this situation until quickcheck
/rand
, but it must have occurred elsewhere. Or maybe its just rare for crates to rexport symbols as part of their API?
For the serde
case, my intuition is that it would be rare to depend on two crates using the same version of the Serialize
/Deserialize
traits, and they work just as well if they're independent. Or maybe its easier for everyone to use a common version of the crates because the API is more stable than (say) rand
?
(edit: I also created an api-guidelines issue)