With traits that are meant to be used as trait bounds, it can often be nice to add blanket impls for &T, &mut T, Rc<T>, Arc<T>, Box<T>.
This is an example from the futures library. They seem to use a number of things like macros to make this more convenient, as well as Pin impls that use Deref.
I was wondering if there are any gotcha's from just using this instead of spelling out all of the wrapper types:
pub trait Assoc
{
fn assoc( &self );
}
impl<A, T> Assoc for T
where
A: Assoc,
T: std::ops::Deref<Target=A>
{
fn assoc( &self ) { (**self).assoc() }
}
This can cause problems if you ever want to make additional blanket impls. Rust has no concept of traits being disjoint from each other, so a blanket impl for T: Deref will conflict with a blanket impl for T: SomethingElse.
It could potentially conflict with specific impls as well. If you try to impl Assoc for ForeignStruct, you'll get a conflict because the crate that defines ForeignStruct might add an implementation of Deref in the future.