I find reflexive impls to be pretty frustrating in Rust. They get in the way of endless conveniences for traits like From
and Borrow
, but at the same time they're great for automating boilerplate and enforcing consistent behavior. I even use blanket impls in my own projects, although I often end up replacing them with manual impls once I realize I want a special case for arrays, tuples, options, etc.
This would most likely be resolved if specialization ever stabilizes, but as an alternative: what if there was a marker trait that represented "simple" (non-complex) types?
Most primitive types (bool
, i32
, Duration
, etc.) would implement this trait, while generic structures (Option<T>
, [T; N]
, (T,U,..)
, etc.) would not. In general, it could be implemented for non-generic types automatically unless they explicitly opt-out with a negative impl, while generic types could explicitly opt-in with a manual impl.
Consequently, reflexive impls could be changed to impl<T> Trait<T> for T where T: Simple
, and non-simple types would be able to provide specialized impls (e.g. impl<T, U> From<Option<U>> for Option<T> where T: From<U>
).
Backwards compatible? Probably not, unless everything implements Simple
and has to explicitly opt-out by default (even generic structures). In that case I think it would be backwards compatible, so long as the standard library opts out of Simple
and provides impls where relevant.