Supertraits and Coherence @BoxyUwU @WaffleLapkin @lcnr
pub trait Super {}
pub trait Sub<T>: Super {}
pub trait Overlap<T> {}
impl<T, U: Sub<T>> Overlap<T> for U {}
impl<T> Overlap<T> for () {}
Solution
Coherence is responsible for checking whether the two impls of Overlap overlap, and if so emitting an error.
In order for these two impls to overlap there must be some type T for which () implements Sub<T>.
The Sub trait is public so downstream crate could exist which implement (): Sub<Local>.
In theory this should mean that these impls overlap, however, the supertrait Super can't be implement for the type () by any downstream crates as impl Super for () { would not pass the orphan check in downstream crates. This logic allows for coherence to consider these impls to not overlap.
If we were to introduce an impl of (): Super to this example then coherence would (rightly) forbid this code.
Note: This example previously did not compile. Coherence was too conservative and rejected this on the basis that
(): Sub<Local>may be implementable by downstream crates. This improvement to coherence occurred when coherence started using the next-gen trait solver on stable.