Description
The following code fails to compile
use std::ops::Range;
struct Foo;
impl From<<Range<usize> as Iterator>::Item> for Foo {
fn from(_: <Range<usize> as Iterator>::Item) -> Foo {
Foo
}
}
The error message is:
error[E0119]: conflicting implementations of trait `std::convert::From<Foo>` for type `Foo`:
--> src/main.rs:5:1
|
5 | impl From<<Range<usize> as Iterator>::Item> for Foo {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T> From<T> for T;
It looks like the compiler thinks that somehow <Range<usize> as Iterator>::Item
might be equal to Foo
, even though Foo
is a local type that the foreign impl or Iterator
for Range<usize>
cannot possibly refer to.
Furthermore, it looks like the compiler does not even try to evaluate <Range<usize> as Iterator>::Item
to decide if the impl is conflicting or not. All associated types from foreign trait implementations (the code compiles fine if a local trait is used instead of Iterator
) seem to always be considered to be in conflict with every possible other type.
For example impl From<(u32, <Range<usize> as Iterator>::Item)> for Foo
and impl From<(u32, String)> for Foo
are also treated as conflicting with each other, even though <Range<usize> as Iterator>::Item
is not String
.
I'm not sure if this last example is a bug (it seems to depend on whether changing an associated type is considered a breaking change or not), but I believe at least the first example should compile, as there is nothing the foreign crate could do to make this impl conflicting.
Meta
This reproduces easily on the playpen, on both stable (1.52.1), beta (1.53.0) and nightly.