Add hints when intercrate ambiguity causes overlap.
I'm going to tackle #23980.
# Examples
## Trait impl overlap caused by possible downstream impl
```rust
trait Foo<X> {}
trait Bar<X> {}
impl<X, T> Foo<X> for T where T: Bar<X> {}
impl<X> Foo<X> for i32 {}
fn main() {}
```
```
error[E0119]: conflicting implementations of trait `Foo<_>` for type `i32`:
--> test1.rs:4:1
|
3 | impl<X, T> Foo<X> for T where T: Bar<X> {}
| ------------------------------------------ first implementation here
4 | impl<X> Foo<X> for i32 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`
|
= note: downstream crates may implement Bar
error: aborting due to previous error
```
## Trait impl overlap caused by possible upstream update
```rust
trait Foo {}
impl<T> Foo for T where T: ::std::fmt::Octal {}
impl Foo for () {}
fn main() {}
```
```
error[E0119]: conflicting implementations of trait `Foo` for type `()`:
--> test2.rs:3:1
|
2 | impl<T> Foo for T where T: ::std::fmt::Octal {}
| ----------------------------------------------- first implementation here
3 | impl Foo for () {}
| ^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
|
= note: upstream crates may add new impl for std::fmt::Octal in future versions
error: aborting due to previous error
```
## Inherent impl overlap caused by possible downstream impl
```rust
trait Bar<X> {}
struct A<T, X>(T, X);
impl<X, T> A<T, X> where T: Bar<X> { fn f(&self) {} }
impl<X> A<i32, X> { fn f(&self) {} }
fn main() {}
```
```
error[E0592]: duplicate definitions with name `f`
--> test3.rs:4:38
|
4 | impl<X, T> A<T, X> where T: Bar<X> { fn f(&self) {} }
| ^^^^^^^^^^^^^^ duplicate definitions for `f`
5 | impl<X> A<i32, X> { fn f(&self) {} }
| -------------- other definition for `f`
|
= note: downstream crates may implement Bar
error: aborting due to previous error
```
## Inherent impl overlap caused by possible upstream update
```rust
struct A<T>(T);
impl<T> A<T> where T: ::std::fmt::Octal { fn f(&self) {} }
impl A<()> { fn f(&self) {} }
fn main() {}
```
```
error[E0592]: duplicate definitions with name `f`
--> test4.rs:3:43
|
3 | impl<T> A<T> where T: ::std::fmt::Octal { fn f(&self) {} }
| ^^^^^^^^^^^^^^ duplicate definitions for `f`
4 | impl A<()> { fn f(&self) {} }
| -------------- other definition for `f`
|
= note: upstream crates may add new impl for std::fmt::Octal in future versions
error: aborting due to previous error
```