I rely on the compiler to tell me when generic bounds on my types/impls are insufficient and which trait constraints are missing, but the compiler never tells me when my generics are over-constrained.
Is there a tool for finding generics with constraints that are unneeded by any part of the implementation?
For example, if I had some wrapper around a HashMap and a custom impl for get:
struct MyWrapper<K, V> {
inner: HashMap<K, V>,
}
impl<K: Eq + Hash + Serialize, V> MyWrapper<K, V> {
pub fn my_get(&self, key: &K) -> Option<&V> {
self.inner.get(key)
}
}
And let's say HashMap requires the key K to be Eq + Hash, but not Serialize, then it would be nice to run some tool that says, "Excuse me, but you're over-constraining your impl and you could remove Serialize if you'd like".
Are there any tools like this?
As far as I know, there isn't anything that does this. Here's some examples where you want traits even though you're not "using" them.
Eq, the implementation ofHashMapdoesn't actually requireEq, in that code would still compile if that trait was removed. This is also relevant if you're writing an alternative thread spawner. Rust doesn't intrinsically know when something needs to beSend; the spawn function has to tell rust this is required.dyn Anyand back. Rust isn't going to know that the value needs to preserve its trait bounds through the conversion todyn Any.Something that might help is to put the trait bounds on the function instead of the impl block:
This is nice if you have some trait bounds that are always needed, but many others that are only needed once or twice.