I think the reason is a type for N can first be written where it does not implement Foo and then a later code change implements it.
With slight addition;
impl<N, L: ::std::fmt::Display> Foo<L> for Vec<N> where N: Foo<L> { fn x() -> u32 { 13u32 }}
error[E0119]: conflicting implementations of trait `Foo<std::vec::Vec<_>>` for type `std::vec::Vec<_>`:
--> src/main.rs:6:1
|
4 | impl<L> Foo<L> for L { default fn x() -> u32 { 12u32 }}
| -------------------- first implementation here
5 | // error conflicting implementations
6 | impl<N, L: ::std::fmt::Display> Foo<L> for Vec<N> where N: Foo<L> { fn x() -> u32 { 13u32 }}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::vec::Vec<_>`
|
= note: upstream crates may add new impl of trait `std::fmt::Display` for type `std::vec::Vec<_>` in future versions
After writing it I though about it a bit more one the
train and came to roughly the same conclusion.
What I want is a way to resolve "conflicting implementations"
where a later wild-card implementation can contain a former
one, i.e. you could say that I broaden the implementation
instead of specializing it (ironically I would even prever to
keep the impl of the first impl line adding all other from
the second).
The scary think I just became aware of is, that many
of the cases I ran into and though specialization will
solve this when available won't be solved, I would
even say that the majority of cases won't be solved.
Specialization still works fine for it's typical purposes
as optimization tool but I fare that might not be what
rust needs, I fare it might need a "conflicting implementation"
solving solution which happens to also enable spcialization...
But then I have not looked into it to much so I think
I probably have to do some research before ranting
more . I just hope that rust is not actually going
into a bad direction.
I’d have expected your first code snippet to compile. Vec<N> is more specific than the blanket impl and should resolve the overlap. It looks like the compiler is worried about the generic parameter of Foo - if you make it non-generic, the code compiles. It seems like it thinks you can end up with duplicate Foo<...> across the two impls, but I don’t understand why that’s relevant. I’ve also lost track of where specialization stands today, what works, what doesn’t temporarily vs permanently, etc